Convertir una fila de un marco de datos en un vector


116

Quiero crear un vector a partir de una fila de un marco de datos. Pero no quiero tener que tener nombres de filas y columnas. Probé varias cosas ... pero no tuve suerte.

Este es mi marco de datos:

> df <- data.frame(a=c(1,2,4,2),b=c(2,6,2,1),c=c(2.6,8.2,7.5,3))
> df
  a b   c
1 1 2 2.6
2 2 6 8.2
3 4 2 7.5
4 2 1 3.0

Lo intenté:

> newV <- as.vector(df[1,])
> newV
  a b   c
1 1 2 2.6

Pero realmente quiero algo parecido a esto:

> newV <- c( 1,2,2.6)
> newV
[1] 1.0 2.0 2.6

Le sugiero que formatee los datos que ha mostrado correctamente. Parece que le faltan algunos saltos de línea.
Chinmay Patil

Quiero una pelea. Fila '1' y no columna 'a'.
Joko

¿Hay alguna forma de aplicar esto a todas las filas de un marco de datos y, por lo tanto, fusionar todos los vectores en un solo vector?
stephanmg

1
@stephanmg: ¿Qué tal algo como c(t(as.matrix(df))):?
Andri Signorell

Andri: Eso está funcionando, aunque también podría resolverlo de otra manera.
stephanmg

Respuestas:


154

Cuando extrae una sola fila de un marco de datos, obtiene un marco de datos de una fila. Conviértalo en un vector numérico:

as.numeric(df[1,])

Como sugiere @Roland, unlist(df[1,])convertirá el marco de datos de una fila en un vector numérico sin eliminar los nombres. Por unname(unlist(df[1,]))lo tanto, es otra forma un poco más explícita de llegar al mismo resultado.

Como @Josh comenta a continuación, si tiene un marco de datos no completamente numérico (alfabético, factorial, mixto ...), necesita en su as.character(df[1,])lugar.


podría ser +1 (o 0 votos en contra) al OP por dar un código que ilustre claramente lo que querían a pesar de que el texto y el título de la pregunta estaban distorsionados ...
Ben Bolker

@ChinmayPatil, ¿cuáles son sus otras opciones? Su ejemplo de código ciertamente hace que parezca que eso es lo que quieren.
Ben Bolker

2
Cabe señalar que un marco de datos ya es un vector y, por lo tanto, as.vector ve que es un vector de modo "lista" y no hace nada. Para facilitar la comprensión de los mecanismos subyacentes, pruebe as.vector (df [1,], mode = "numeric") que es más ilustrativo. Esto es lo que hace as.numeric.

1
No hay problema. Solo digo que para este problema dan exactamente la misma respuesta.
Ben Bolker

1
Es posible que se haya cambiado mientras tanto, pero hoy unlist permite eliminar nombres: identical(unlist(df[1,], use.names = FALSE), as.numeric(df[1,])) (y por cierto df todavía no es un nombre sensato para un data.frame ... ;-))
Andri Signorell

45

Recomiendo unlist, que mantiene los nombres.

unlist(df[1,])
  a   b   c 
1.0 2.0 2.6 

is.vector(unlist(df[1,]))
[1] TRUE

Si no quiere un vector con nombre:

unname(unlist(df[1,]))
[1] 1.0 2.0 2.6

7

Si no desea cambiar a numérico, puede intentar esto.

> as.vector(t(df)[,1])
[1] 1.0 2.0 2.6

3
esto no tiene mucho sentido para mí: str(as.vector(t(df)[,1]))es num [1:3] 1 2 2.6, es decir, su código no convertir los resultados a un vector numérico ...
Ben Bolker

2
específicamente, cuando usa t(df)R convierte el marco de datos en una matriz, en este caso una matriz numérica porque todos los elementos son numéricos. Luego [,1]extrae la primera columna (un vector numérico, porque la dimensión redundante se elimina automáticamente). as.vector()simplemente suelta los nombres (lo que también podría hacer unname()).
Ben Bolker

Parece funcionar también para los personajes. Pero tienes razón sobre la coerción. FWIW, mi solución también funcionará en marcos de datos de caracteres ... con la advertencia de que todos los datos se convierten en caracteres
Chinmay Patil

2
Yo diría que la unname(unlist(x))solución es un poco mejor (más eficiente y más transparente).
Ben Bolker

as.vector(t(df)[,1])Me encanta ! ¡Exactamente lo que lo necesito!
Uther Pendragon

7

Aquí hay una dplyropción basada:

newV = df %>% slice(1) %>% unlist(use.names = FALSE)

# or slightly different:
newV = df %>% slice(1) %>% unlist() %>% unname()

2

Tenga en cuenta que debe tener cuidado si su fila contiene un factor. Aquí hay un ejemplo:

df_1 = data.frame(V1 = factor(11:15),
                  V2 = 21:25)
df_1[1,] %>% as.numeric() # you expect 11 21 but it returns 
[1] 1 21

Aquí hay otro ejemplo (por defecto, data.frame () convierte caracteres en factores)

df_2 = data.frame(V1 = letters[1:5],
                  V2 = 1:5)
df_2[3,] %>% as.numeric() # you expect to obtain c 3 but it returns
[1] 3 3
df_2[3,] %>% as.character() # this won't work neither
[1] "3" "3"

Para evitar este comportamiento, es necesario cuidar el factor, antes de extraerlo:

df_1$V1 = df_1$V1 %>% as.character() %>% as.numeric()
df_2$V1 = df_2$V1 %>% as.character()
df_1[1,] %>% as.numeric()
[1] 11  21
df_2[3,] %>% as.character()
[1] "c" "3"

-3

Las columnas de los marcos de datos ya son vectores, solo tiene que extraerlos. Tenga en cuenta que coloca la columna que desea después de la coma, no antes:

> newV <- df[,1]
> newV
[1] 1 2 4 2

Si realmente quieres una fila, haz lo que dijo Ben y usa las palabras correctamente en el futuro.


pero creo que el OP quiere la primera fila ?
Ben Bolker

1
@BenBolker Quizás sí ... Simplemente asumí que quería lo que su título y pregunta decían que quería.
Jonathan Christensen
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.