Extraer columnas específicas de un marco de datos

366

Tengo un marco de datos R con 6 columnas, y quiero crear un nuevo marco de datos que solo tenga tres de las columnas.

Suponiendo mi trama de datos es df, y quiero columnas de extracto A, By E, este es el único comando que puedo averiguar:

 data.frame(df$A,df$B,df$E)

¿Hay una forma más compacta de hacer esto?

Aren Cambre
fuente

Respuestas:

157

Usando el paquete dplyr , si se llama a su data.frame df1:

library(dplyr)

df1 %>%
  select(A, B, E)

Esto también se puede escribir sin la %>%tubería como:

select(df1, A, B, E)
Sam Firke
fuente
2
Dada la considerable evolución del Tidyverse desde que publiqué mi pregunta, te he cambiado la respuesta.
Aren Cambre
44
Dada la furiosa tasa de cambio en el tidyverse, advertiría contra el uso de este patrón. Esto se suma a mi fuerte preferencia por tratar los nombres de columnas como si fueran nombres de objetos al escribir código para funciones, paquetes o aplicaciones.
Joshua Ulrich
1
Han pasado más de cuatro años desde que se envió esta respuesta, y el patrón no ha cambiado. Las expresiones canalizadas pueden ser bastante intuitivas, por lo que son atractivas.
Aren Cambre
¿Cómo ejecuto un comando adicional en este subconjunto? Por ejemplo, quiero calcular el rowMean: "df1%>% rowMeans (select (A, B, E))" no funciona.
Ben
Más le encadenar una tubería como: df1 %>% select(A, B, E) %>% rowMeans(.). Consulte la documentación de la %>%tubería escribiendo?magrittr::`%>%`
Sam Firke,
448

Puede subconjunto usando un vector de nombres de columna. Prefiero este enfoque sobre aquellos que tratan los nombres de columna como si fueran nombres de objetos (por ejemplo subset()), especialmente cuando se programa en funciones, paquetes o aplicaciones.

# data for reproducible example
# (and to avoid confusion from trying to subset `stats::df`)
df <- setNames(data.frame(as.list(1:5)), LETTERS[1:5])
# subset
df[,c("A","B","E")]
Joshua Ulrich
fuente
44
Eso da el error object of type 'closure' is not subsettable.
Aren Cambre
24
@ArenCambre: entonces tu data.frame no se llama realmente df. dfTambién es una función en el paquete de estadísticas.
Joshua Ulrich
2
@Cina: Porque -"A"es un error de sintaxis. Y ?Extractdice, " , también pueden ser números enteros negativos, lo que indica elementos / rebanadas de dejar fuera de la selección." ij...
Joshua Ulrich
77
Hay un problema con esta sintaxis, porque si extraemos sólo una columna R, devuelve un vector en vez de una trama de datos y esto podría ser no deseado: > df[,c("A")] [1] 1. Usar subsetno tiene esta desventaja.
David Dorchies
101

Este es el papel de la subset()función:

> dat <- data.frame(A=c(1,2),B=c(3,4),C=c(5,6),D=c(7,7),E=c(8,8),F=c(9,9)) 
> subset(dat, select=c("A", "B"))
  A B
1 1 3
2 2 4
Stéphane Laurent
fuente
Cuando intento esto, con mis datos, aparece el error: "Error en x [j]: tipo de subíndice no válido 'lista'" Pero si c ("A", "B") no es una lista, ¿qué es? ?
Rafael_Espericueta
@Rafael_Espericueta Difícil de adivinar sin ver su código ... Pero c("A", "B")es un vector, no una lista.
Stéphane Laurent
Convierte el marco de datos a la lista.
Suat Atan PhD
78

Hay dos opciones obvias: Joshua Ulrich's df[,c("A","B","E")]o

df[,c(1,2,5)]

como en

> df <- data.frame(A=c(1,2),B=c(3,4),C=c(5,6),D=c(7,7),E=c(8,8),F=c(9,9)) 
> df
  A B C D E F
1 1 3 5 7 8 9
2 2 4 6 7 8 9
> df[,c(1,2,5)]
  A B E
1 1 3 8
2 2 4 8
> df[,c("A","B","E")]
  A B E
1 1 3 8
2 2 4 8
Enrique
fuente
16

Solo por alguna razón

df[, (names(df) %in% c("A","B","E"))]

trabajó para mi. Todas las sintaxis anteriores produjeron "columnas indefinidas seleccionadas".

so860
fuente
15

Donde df1 es su marco de datos original:

df2 <- subset(df1, select = c(1, 2, 5))
Richard Ball
fuente
77
Esto no usa dplyr. Utiliza base::subset, y es idéntico a la respuesta de Stephane Laurent, excepto que utiliza números de columna en lugar de nombres de columna.
Gregor Thomas
14

También puede usar el sqldfpaquete que realiza selecciones en marcos de datos R como:

df1 <- sqldf("select A, B, E from df")

Esto da como resultado un marco de datos df1con columnas: A, B, E.

Aman Burman
fuente
2

Puedes usar with:

with(df, data.frame(A, B, E))
Moody_Mudskipper
fuente
1
df<- dplyr::select ( df,A,B,C)

Además, puede asignar un nombre diferente a los datos recién creados

data<- dplyr::select ( df,A,B,C)
Mohamed Rahouma
fuente
0

[ y subconjunto no son sustituibles:

[ devuelve un vector si solo se selecciona una columna.

df = data.frame(a="a",b="b")    

identical(
  df[,c("a")], 
  subset(df,select="a")
) 

identical(
  df[,c("a","b")],  
  subset(df,select=c("a","b"))
)
fxi
fuente
44
No si te pones drop=FALSE. Ejemplo:df[,c("a"),drop=F]
hasta el