2012-08-31 17 views
33

Estoy familiarizado con ser capaz de extraer las columnas de una trama de datos R (o matriz), así:Selección de columnas en la trama de datos basados ​​en los que R * no * en un vector

df.2 <- df[, c("name1", "name2", "name3")] 

Pero puede uno utilice una herramienta ! u otra para seleccionar todas excepto las columnas enumeradas?

Para el fondo, que tienen una trama de datos con unos vectores de columna bastante y me gustaría evitar:

  • Escribiendo a cabo la mayoría de los nombres cuando tan sólo pudiera eliminar una minoría
  • Uso el mucho más corto df.2 <- df[, c(1,3,5)] porque cuando mi archivo .csv cambia, mi código se vuelve obvio ya que la numeración ya no es la misma. Soy nuevo en R y creo haber aprendido de la manera difícil de no usar vectores numéricos para df's más grandes que puedan cambiar.

me trataron:

df.2 <- df[, !c("name1", "name2", "name3")] 
df.2 <- df[, !=c("name1", "name2", "name3")] 

Y justo cuando estaba escribiendo esto, se enteraron de que esto funciona:

df.2 <- df[, !names(df) %in% c("name1", "name2", "name3")] 

¿Hay una manera mejor que esto último?

+5

Generalmente, acorto el último ejemplo utilizando un operador de infijo personalizado: ''% ni%' <- Negate ('% en%')'. – joran

+0

@joran ¿Eso no solo lo acorta con un '!'? ¿O me estoy perdiendo algo? – Hendy

+1

Sí, aunque la mayoría de la gente usa() para que guarden otro 2. Es más acerca de la legibilidad para mí. – joran

Respuesta

2

Puede hacer una función personalizada para hacer esto si la está utilizando para su uso personal para manipular datos. Puedo hacer algo como esto:

rm.col <- function(df, ...) { 
    x <- substitute(...()) 
    z <- Trim(unlist(lapply(x, function(y) as.character(y)))) 
    df[, !names(df) %in% z] 
} 

rm.col(mtcars, hp, mpg) 

El primer argumento es el nombre trama de datos. los siguientes ... son los nombres de las columnas que desea eliminar.

10

Usted puede hacer una llamada más corta que también es más generalizable con grep-negativo:

df.2 <- df[, -grep("^name[1:3]$", names(df))] 

Desde grep devuelve los valores numéricos se puede utilizar la indexación del vector negativo para eliminar columnas. Puede agregar más números o más patrones complejos.

23

Una alternativa a grep es which:

df.2 <- df[, -which(names(df) %in% c("name1", "name2", "name3"))] 
+0

La técnica aquí es la misma que en Data.table, pero una coma más que 'myData [,,! RemoveCols]'. – hhh

-1

La forma más sencilla que viene a la mente:

filtered_df < -df [, setdiff (nombres (df), c ("nombre1 "," name2 ")]

esencialmente usted está calculando la diferencia establecida entre la lista completa de nombres de columna y el subconjunto que desea para filtrar (nombre1 y nombre2 arriba).

1

hilo viejo, pero aquí hay otra solución:

df.2 <- subset(df, select=-c(name1, name2, name3)) 

Este fue publicada en otro hilo similar (aunque yo no lo encuentro en este momento). Debe ser un código sostenible en la situación que describes, y probablemente sea más fácil de leer y editar que algunas de las otras opciones.

+0

El enfoque de data.frame es lo mismo que con data.table de modo que 'subconjunto (myData ,,! Names (myData)% en% removeCols)' donde hay una diferencia de coma, irritantemente similar. Pero este enfoque con 'select = -c (..)' no funciona, ¿por qué ideas? – hhh

+0

¡Hmm, no tengo idea! No uso data.table's – mfloren

1

dplyr::select tiene varias opciones para quitar columnas específicas:

library(dplyr) 

drop_columns <- c('cyl','disp','hp') 
mtcars %>% 
    select(-one_of(drop_columns)) %>% 
    head(2) 

       mpg drat wt qsec vs am gear carb 
Mazda RX4  21 3.9 2.620 16.46 0 1 4 4 
Mazda RX4 Wag 21 3.9 2.875 17.02 0 1 4 4 

Negando nombres de las columnas específicas, la siguiente gotas de la columna de "HP" y las columnas de "QseC" a través de "artes":

mtcars %>% 
    select(-hp, -(qsec:gear)) %>% 
    head(2) 

       mpg cyl disp drat wt carb 
Mazda RX4  21 6 160 3.9 2.620 4 
Mazda RX4 Wag 21 6 160 3.9 2.875 4 

también puede negar , starts_with(), ends_with() o matches():

mtcars %>% 
    select(-contains('t')) %>% 
    select(-starts_with('a')) %>% 
    select(-ends_with('b')) %>% 
    select(-matches('^m.+g$')) %>% 
    head(2) 

       cyl disp hp qsec vs gear 
Mazda RX4  6 160 110 16.46 0 4 
Mazda RX4 Wag 6 160 110 17.02 0 4 
+1

No estoy seguro de que esto sea más claro/superior que otros, pero aprecio actualizar con nuevas herramientas [ish] cuando salgan. Gracias por agregar esto para mantener las cosas frescas. – Hendy

Cuestiones relacionadas