¿Convertir la columna data.frame a un vector?


164

Tengo un marco de datos como:

a1 = c(1, 2, 3, 4, 5)
a2 = c(6, 7, 8, 9, 10)
a3 = c(11, 12, 13, 14, 15)
aframe = data.frame(a1, a2, a3)

Intenté lo siguiente para convertir una de las columnas en un vector, pero no funciona:

avector <- as.vector(aframe['a2'])
class(avector) 
[1] "data.frame"

Esta es la única solución que se me ocurre, pero supongo que tiene que haber una mejor manera de hacerlo:

class(aframe['a2']) 
[1] "data.frame"
avector = c()
for(atmp in aframe['a2']) { avector <- atmp }
class(avector)
[1] "numeric"

Nota: Mi vocabulario anterior puede estar apagado, así que corrígeme si es así. Todavía estoy aprendiendo el mundo de R. Además, cualquier explicación de lo que está sucediendo aquí es apreciada (¡es decir, relacionarse con Python o algún otro idioma ayudaría!)


55
Como está viendo en las respuestas, una lectura ?'[.data.frame'detallada de lo llevará muy lejos.
joran

Respuestas:


208

Intentaré explicar esto sin cometer errores, pero apuesto a que esto atraerá una aclaración o dos en los comentarios.

Un marco de datos es una lista. Cuando subconjusta un marco de datos usando el nombre de una columna y [, lo que obtienes es una sublista (o un sub marco de datos). Si desea la columna atómica real, podría usar [[, o algo confuso (para mí) que podría hacer, aframe[,2]que devuelve un vector, no una sublista.

Intenta ejecutar esta secuencia y tal vez las cosas estén más claras:

avector <- as.vector(aframe['a2'])
class(avector) 

avector <- aframe[['a2']]
class(avector)

avector <- aframe[,2]
class(avector)

66
+1 Esto es útil. Me había acostumbrado a usar aframe[,"a2"]debido a la capacidad de usar esto tanto con marcos de datos como con matrices y parece que obtengo los mismos resultados: un vector.
Iterador

8
[..., drop = F]siempre devolverá un marco de datos
hadley

1
Es particularmente bueno saberlo porque la df$xsintaxis devuelve un vector. Utilicé esta sintaxis durante mucho tiempo, pero cuando tuve que comenzar a usar df['name']o df[n]recuperar columnas, tuve problemas cuando intenté enviarlas a funciones que esperaban vectores. Usar df[[n]]o df[['x']]aclarar las cosas de inmediato.
rensa

8
¿Por qué as.vectorparece no tener ningún efecto en silencio? ¿No debería esto devolver un vector o fallar notablemente?
bli

aframe[['a2']]es muy útil con sfobjetos porque aframe[,"a2"]devolverá dos columnas porque se incluye la columna de geometría.
Matt

41

Ahora hay una manera fácil de hacer esto usando dplyr.

dplyr::pull(aframe, a2)

32

Puedes usar $extracción:

class(aframe$a1)
[1] "numeric"

o el corchete doble:

class(aframe[["a1"]])
[1] "numeric"

21

No es necesario as.vector(), pero sí necesita una indexación correcta:avector <- aframe[ , "a2"]

La otra cosa a tener en cuenta es la drop=FALSEopción de [:

R> aframe <- data.frame(a1=c1:5, a2=6:10, a3=11:15)
R> aframe
  a1 a2 a3
1  1  6 11
2  2  7 12
3  3  8 13
4  4  9 14
5  5 10 15
R> avector <- aframe[, "a2"]
R> avector
[1]  6  7  8  9 10
R> avector <- aframe[, "a2", drop=FALSE]
R> avector
  a2
1  6
2  7
3  8
4  9
5 10
R> 

44
+1: El recordatorio drop=FALSEes útil: esto me ayuda en los casos en que puedo seleccionar N columnas de un marco de datos, en aquellos casos en que N = 1.
Iterator

Lo uso cuando no puedo prever el número de columnas seleccionadas y en caso de que aparezca una columna, el resultado todavía se pasa como un data.frame con n columnas. Un vector puede arrojar una llave inglesa en las funciones en la línea.
Roman Luštrik

11

Otra ventaja de usar el operador '[[' 'es que funciona tanto con data.frame como con data.table. Entonces, si la función debe ejecutarse tanto para data.frame como para data.table, y desea extraer una columna de ella como un vector, entonces

data[["column_name"]] 

es mejor.


8

Puedes probar algo como esto

as.vector(unlist(aframe$a2))

Esto es bueno si quiere comparar dos columnas usando identical.
p-robot

5

Si solo usa el operador de extracción, funcionará. Por defecto, [] establece la opción drop=TRUE, que es lo que desea aquí. Ver ?'['para más detalles.

>  a1 = c(1, 2, 3, 4, 5)
>  a2 = c(6, 7, 8, 9, 10)
>  a3 = c(11, 12, 13, 14, 15)
>  aframe = data.frame(a1, a2, a3)
> aframe[,'a2']
[1]  6  7  8  9 10
> class(aframe[,'a2'])
[1] "numeric"


3
a1 = c(1, 2, 3, 4, 5)
a2 = c(6, 7, 8, 9, 10)
a3 = c(11, 12, 13, 14, 15)
aframe = data.frame(a1, a2, a3)
avector <- as.vector(aframe['a2'])

avector<-unlist(avector)
#this will return a vector of type "integer"

2

Utilizo listas para filtrar marcos de datos según tengan o no un valor% en% una lista.

Había estado creando listas manualmente exportando un marco de datos de 1 columna a Excel donde agregaría "", alrededor de cada elemento, antes de pegar en R: list <- c ("el1", "el2", ...) que generalmente era seguido de FilteredData <- subconjunto (Datos, Columna% en la lista%).

Después de buscar stackoverflow y no encontrar una forma intuitiva de convertir un marco de datos de 1 columna en una lista, ahora estoy publicando mi primera contribución de stackoverflow:

# assuming you have a 1 column dataframe called "df"
list <- c()
for(i in 1:nrow(df)){
  list <- append(list, df[i,1])
}
View(list)
# This list is not a dataframe, it is a list of values
# You can filter a dataframe using "subset([Data], [Column] %in% list")

1

También podemos convertir columnas data.frame genéricamente en un vector simple. as.vectorno es suficiente ya que retiene la clase y la estructura data.frame, por lo que también tenemos que extraer el primer (y único) elemento:

df_column_object <- aframe[,2]
simple_column <- df_column_object[[1]]

Todas las soluciones sugeridas hasta ahora requieren títulos de columna de codificación fija. Esto los hace no genéricos (imagine aplicar esto a los argumentos de la función).

Alternativamente, podría, por supuesto, leer primero los nombres de columna de la columna y luego insertarlos en el código en las otras soluciones.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.