Tengo varias columnas que me gustaría eliminar de un marco de datos. Sé que podemos eliminarlos individualmente usando algo como:
df$x <- NULL
Pero esperaba hacer esto con menos comandos.
Además, sé que podría soltar columnas usando una indexación de enteros como esta:
df <- df[ -c(1, 3:6, 12) ]
Pero me preocupa que la posición relativa de mis variables pueda cambiar.
Dado lo poderoso que es R, pensé que podría haber una mejor manera que soltar cada columna una por una.

df#drop(var_name), y en su lugar, tenemos que hacer estas soluciones complicadas?Respuestas:
Puede usar una lista simple de nombres:
O, alternativamente, puede hacer una lista de los que desea conservar y hacer referencia a ellos por su nombre:
EDITAR: Para aquellos que aún no están familiarizados con el
dropargumento de la función de indexación, si desea mantener una columna como marco de datos, debe:drop=TRUE(o no mencionarlo) eliminará dimensiones innecesarias y, por lo tanto, devolverá un vector con los valores de la columnay.fuente
DF[,keeps]lugar deDF[keeps]?También está el
subsetcomando, útil si sabe qué columnas desea:ACTUALIZADO después del comentario de @hadley: Para colocar las columnas a, c, podría hacer:
fuente
subsetfunción R tuviera una opción como "allbut = FALSE", que "invierte" la selección cuando se establece en TRUE, es decir, conserva todas las columnas excepto las de laselectlista.df[c("a", "c")]subsetorden en el que no hay que poner comillas alrededor de los nombres de columna - supongo que no me importa escribir algunos caracteres adicionales sólo para evitar citar nombres :)subsetdentro de otras funciones.es probablemente la más fácil, o para múltiples variables:
O si está tratando con
data.tables (según ¿Cómo elimina una columna por nombre en data.table? ):o para múltiples variables
fuente
within(df, rm(x))Es, con mucho, la solución más limpia. Dado que esta es una posibilidad, cualquier otra respuesta parece innecesariamente complicada por un orden de magnitud.within(df, rm(x))se no funciona si hay columnas duplicadas nombradasxendf.df <- data.frame(x = 1, y = 2); names(df) <- c("x", "x"); within(df, rm(x))devolucionesdata.frame(x = 2, x = 2).within()que es poderosa pero que también usa NSE. La nota en la página de ayuda establece claramente que para la programación se debe tener cuidado suficiente.Podrías usar
%in%así:fuente
DF[ , !(names(DF) %in% drops)]identical(post_time_1, post_time_2) [1] TRUE= Dlist (NULL) también funciona:
fuente
Si desea eliminar las columnas por referencia y evitar la copia interna asociada con
data.frames, puede usar eldata.tablepaquete y la función:=Puede pasar los nombres de un vector de caracteres al lado izquierdo del
:=operador, yNULLcomo el RHS.Si desea predefinir los nombres como vector de caracteres fuera de la llamada a
[, ajuste el nombre del objeto en()o{}forzar la evaluación del LHS en el alcance de la llamada, no como un nombre dentro del alcance deDT.También puede usar
set, lo que evita la sobrecarga de[.data.table, y también funciona paradata.frames!fuente
Existe una estrategia potencialmente más poderosa basada en el hecho de que grep () devolverá un vector numérico. Si tiene una larga lista de variables como yo en uno de mi conjunto de datos, algunas variables que terminan en ".A" y otras que terminan en ".B" y solo desea las que terminan en ".A" (junto con todas las variables que no coinciden con ninguno de los patrones, haga esto:
Para el caso en cuestión, utilizando el ejemplo de Joris Meys, podría no ser tan compacto, pero sería:
fuente
dropsen primer lugar comopaste0("^", drop_cols, "$"), esto se vuelve mucho más agradable (leer: más compacto) consapply:DF[ , -sapply(drops, grep, names(DF))]Otra
dplyrrespuesta Si sus variables tienen alguna estructura de nombres común, puede intentarlostarts_with(). Por ejemploSi desea soltar una secuencia de variables en el marco de datos, puede usar
:. Por ejemplo, si quisiera eliminarvar2,var3y todas las variables intermedias, simplemente le quedaríavar1:fuente
select(), comocontains()omatches(), que también acepta expresiones regulares.Otra posibilidad:
o
fuente
setdiffes el óptimo, especialmente en el caso de una gran cantidad de columnas.df <- df[ , -which(grepl('a|c', names(df)))]Salida:
Salida:
fuente
Solución Dplyr
Dudo que esto reciba mucha atención aquí, pero si tiene una lista de columnas que desea eliminar y desea hacerlo en una
dplyrcadena que usoone_of()en laselectcláusula:Aquí hay un ejemplo simple y reproducible:
La documentación se puede encontrar ejecutando
?one_ofo aquí:http://genomicsclass.github.io/book/pages/dplyr_tutorial.html
fuente
Por interés, esto señala una de las extrañas inconsistencias de sintaxis múltiple de R. Por ejemplo, dado un marco de datos de dos columnas:
Esto da un marco de datos
pero esto da un vector
Todo esto se explica
?[pero no es exactamente el comportamiento esperado. Bueno, al menos no para mí ...fuente
Aquí hay una
dplyrmanera de hacerlo:Me gusta esto porque es intuitivo para leer y comprender sin anotaciones y robusto para que las columnas cambien de posición dentro del marco de datos. También sigue el idioma vectorizado que se usa
-para eliminar elementos.fuente
%<>%operador para reemplazar el objeto de entrada que podría simplificarsedf %<>% select(-col.to.drop.1, -col.to.drop.2, ..., -col.to.drop.6)dplyrpodría ser más fácil agruparlas y poner solo un menos:df.cut <- df %>% select(-c(col.to.drop.1, col.to.drop.2, ..., col.to.drop.n))Sigo pensando que debe haber un idioma mejor, pero para restar columnas por nombre, tiendo a hacer lo siguiente:
fuente
df[,-match(c("e","f"),names(df))]-?Hay una función llamada
dropNamed()en elBBmiscpaquete de Bernd Bischl que hace exactamente esto.La ventaja es que evita repetir el argumento del marco de datos y, por lo tanto, es adecuado para conectar
magrittr(al igual que losdplyrenfoques):fuente
Otra solución si no desea utilizar @ hadley's arriba: si "COLUMN_NAME" es el nombre de la columna que desea colocar:
fuente
COLUMN_NAMEno está endf(compruebe usted mismo:)df<-data.frame(a=1,b=2). (3)df[,names(df) != "COLUMN_NAME"]es más simple y no sufre de (2)Más allá de lo
select(-one_of(drop_col_names))demostrado en respuestas anteriores, hay un par de otrasdplyropciones para colocar columnasselect()que no implican la definición de todos los nombres de columna específicos (usando los datos de muestra dplyr starwars para alguna variedad en los nombres de columna):Si necesita descartar una columna que puede o no existir en el marco de datos, aquí hay un pequeño giro
select_if()que, a diferencia del usoone_of(), no arrojará unaUnknown columns:advertencia si el nombre de la columna no existe. En este ejemplo, 'bad_column' no es una columna en el marco de datos:fuente
Proporcione el marco de datos y una cadena de nombres separados por comas para eliminar:
Uso :
fuente
Encuentre el índice de las columnas que desea soltar usando
which. Dé a estos índices un signo negativo (*-1). Luego subconjunto en esos valores, lo que los eliminará del marco de datos. Esto es un ejemplo.fuente
Si tiene una
data.framememoria grande y tiene poco uso de memoria[. . . . ormywithinpara eliminar columnas de unadata.frame, comosubsetes actualmente (R 3.6.2) usando más memoria - al lado de la pista del manual para utilizarsubsetde forma interactiva .fuente