web-dev-qa-db-fra.com

Création d'un bloc de données à partir de deux vecteurs à l'aide de cbind

Considérons le code R suivant.

> x = cbind(c(10, 20), c("[]", "[]"), c("[[1,2]]","[[1,3]]"))
> x
     [,1] [,2] [,3]     
[1,] "10" "[]" "[[1,2]]"
[2,] "20" "[]" "[[1,3]]"

De même

> x = rbind(c(10, "[]", "[[1,2]]"), c(20, "[]", "[[1,3]]"))
> x
     [,1] [,2] [,3]     
[1,] "10" "[]" "[[1,2]]"
[2,] "20" "[]" "[[1,3]]"

Maintenant, je ne veux pas les entiers 10 et 20 être converti en chaînes. Comment puis-je effectuer cette opération sans conversion? Je voudrais bien sûr aussi savoir pourquoi cette conversion se produit. J'ai jeté un œil à l'aide de cbind et j'ai également essayé Google, mais je n'ai pas eu la chance de trouver une solution. Je crois aussi que dans certains cas. R convertit les chaînes en facteurs, et je ne veux pas que cela se produise non plus, bien que cela ne semble pas se produire ici.

26
Faheem Mitha

Les vecteurs et les matrices ne peuvent être que d'un seul type et les vecteurs cbind et rbind donneront des matrices. Dans ces cas, les valeurs numériques seront promues en valeurs de caractères car ce type contiendra toutes les valeurs.

(Notez que dans votre exemple rbind, la promotion a lieu dans l'appel c:

> c(10, "[]", "[[1,2]]")
[1] "10"      "[]"      "[[1,2]]"

Si vous voulez une structure rectangulaire où les colonnes peuvent être de types différents, vous voulez un data.frame. N'importe lequel des éléments suivants devrait vous procurer ce que vous voulez:

> x = data.frame(v1=c(10, 20), v2=c("[]", "[]"), v3=c("[[1,2]]","[[1,3]]"))
> x
  v1 v2      v3
1 10 [] [[1,2]]
2 20 [] [[1,3]]
> str(x)
'data.frame':   2 obs. of  3 variables:
 $ v1: num  10 20
 $ v2: Factor w/ 1 level "[]": 1 1
 $ v3: Factor w/ 2 levels "[[1,2]]","[[1,3]]": 1 2

ou (en utilisant spécifiquement le data.frame version de cbind)

> x = cbind.data.frame(c(10, 20), c("[]", "[]"), c("[[1,2]]","[[1,3]]"))
> x
  c(10, 20) c("[]", "[]") c("[[1,2]]", "[[1,3]]")
1        10            []                 [[1,2]]
2        20            []                 [[1,3]]
> str(x)
'data.frame':   2 obs. of  3 variables:
 $ c(10, 20)              : num  10 20
 $ c("[]", "[]")          : Factor w/ 1 level "[]": 1 1
 $ c("[[1,2]]", "[[1,3]]"): Factor w/ 2 levels "[[1,2]]","[[1,3]]": 1 2

ou (en utilisant cbind, mais en faisant le premier un data.frame pour qu’il se combine comme le fait data.frames):

> x = cbind(data.frame(c(10, 20)), c("[]", "[]"), c("[[1,2]]","[[1,3]]"))
> x
  c.10..20. c("[]", "[]") c("[[1,2]]", "[[1,3]]")
1        10            []                 [[1,2]]
2        20            []                 [[1,3]]
> str(x)
'data.frame':   2 obs. of  3 variables:
 $ c.10..20.              : num  10 20
 $ c("[]", "[]")          : Factor w/ 1 level "[]": 1 1
 $ c("[[1,2]]", "[[1,3]]"): Factor w/ 2 levels "[[1,2]]","[[1,3]]": 1 2
38
Brian Diggs

En utilisant data.frame au lieu de cbind devrait être utile

x <- data.frame(col1=c(10, 20), col2=c("[]", "[]"), col3=c("[[1,2]]","[[1,3]]"))
x
  col1 col2    col3
1   10   [] [[1,2]]
2   20   [] [[1,3]]

sapply(x, class) # looking into x to see the class of each element
     col1      col2      col3 
"numeric"  "factor"  "factor" 

Comme vous pouvez le voir, les éléments de col1 sont numeric comme vous le souhaitez.

data.frame _ peut avoir des variables de class: numeric, factor et character mais matrix pas, une fois que vous avez mis un character élément dans une matrice, tous les autres entreront dans cette classe, quelle que soit la classe où ils se trouvaient auparavant.

14
Jilber Urbina