2012-10-08 32 views
23

Considere el siguiente código de R.Crear un marco de datos a partir de dos vectores utilizando cbind

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

Del mismo modo

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

Ahora, no quiero los números enteros y 1020 que se convierten en cadenas. ¿Cómo puedo realizar esta operación sin dicha conversión? Lo del curso también me gustaría saber por qué ocurre esta conversión. Miré la ayuda cbind y también probé Google, pero no tuve suerte encontrando una solución . También creo que en algunos casos. R convierte cadenas a factores, y tampoco quiero que eso suceda, aunque no parece que esté pasando aquí.

+0

El problema no es con 'cbind', pero con 'C'. Esa es la función que necesita para comprender mejor. –

Respuesta

28

Los vectores y matrices solo pueden ser de un solo tipo y cbind y rbind en vectores darán matrices. En estos casos, los valores numéricos se promoverán a valores de caracteres ya que ese tipo contendrá todos los valores.

(Tenga en cuenta que en su ejemplo rbind, la promoción ocurre dentro del c llamada:.

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

Si desea una estructura rectangular donde las columnas pueden ser de diferentes tipos, que desea una data.frame Cualquiera de los siguientes debe conseguir lo que quiere:

> 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 

o (en concreto con la versión de data.framecbind)

> 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 

o (usando cbind, pero haciendo la primera data.frame una forma que combina como data.frames hacen):

> 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 
+0

Gracias por la respuesta detallada. No creo que necesite las propiedades de los factores aquí, y mi recuerdo es que pueden causar problemas. ¿Hay alguna forma de crear un marco de datos con valores de cadena en su lugar? –

+0

Agregue 'stringsAsFactors = FALSE' a las llamadas' data.frame'.Si las llamadas son implícitas (como en el último ejemplo), debe hacerlas explícitas: 'data.frame (c (" [] "," [] "), stringsAsFactors = FALSE)'. –

+0

Existe una opción global 'stringsAsFactors' que también controla esto. Lo dejo como el predeterminado enviado y lo cambio según sea necesario para la reproducibilidad. –

9

Usando data.frame en lugar de cbind debería ser útil

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" 

Como se puede ver elementos de col1 son numeric como desee.

data.frame puede tener variables de diferente class: numeric, factor y character pero matrix no, una vez que poner un elemento character en una matriz de todos los demás se convierten en esta clase no importa qué clase que eran antes.

+0

Gracias. ¿Puedo convertir la clase de 'col2' y' col3' en una cadena? –

+0

Lo siento, estaba confundido. Quise decir clase 'character' en lugar de' string' para ver qué clases maneja R ver [this] (http://stat.ethz.ch/R-manual/R-patched/library/methods/html /Classes.html), puedes forzar que 'factor' sea' character' haciendo 'as.character (factor)'. –

Cuestiones relacionadas