¿Cómo se elimina una columna por nombre en data.table?

Resuelto Maiasaura asked hace 54 años • 8 respuestas

Para deshacerme de una columna llamada "foo" en a data.frame, puedo hacer:

df <- df[-grep('foo', colnames(df))]

Sin embargo, una vez que dfse convierte en un data.tableobjeto, no hay forma de simplemente eliminar una columna.

Ejemplo:

df <- data.frame(id = 1:100, foo = rnorm(100))
df2 <- df[-grep('foo', colnames(df))] # works
df3 <- data.table(df)
df3[-grep('foo', colnames(df3))] 

Pero una vez que se convierte en un data.tableobjeto, esto ya no funciona.

Maiasaura avatar Jan 01 '70 08:01 Maiasaura
Aceptado

Cualquiera de las siguientes opciones eliminará foola columna de data.table df3:

# Method 1 (and preferred as it takes 0.00s even on a 20GB data.table)
df3[,foo:=NULL]

df3[, c("foo","bar"):=NULL]  # remove two columns

myVar = "foo"
df3[, (myVar):=NULL]   # lookup myVar contents

# Method 2a -- A safe idiom for excluding (possibly multiple)
# columns matching a regex
df3[, grep("^foo$", colnames(df3)):=NULL]

# Method 2b -- An alternative to 2a, also "safe" in the sense described below
df3[, which(grepl("^foo$", colnames(df3))):=NULL]

data.table también admite la siguiente sintaxis:

## Method 3 (could then assign to df3, 
df3[, !"foo"]  

aunque si realmente desea eliminar la columna "foo"( df3en lugar de simplemente imprimir una vista de la df3columna negativa "foo"), realmente querrá usar el Método 1.

(Tenga en cuenta que si utiliza un método que depende de grep()o grepl(), debe establecerlo pattern="^foo$"en lugar de "foo", si no desea que las columnas con nombres como "fool"y "buffoon"(es decir, aquellas que contienen foouna subcadena) también coincidan y se eliminen).

Opciones menos seguras, bien para uso interactivo:

Los siguientes dos modismos también funcionarán, si df3contienen una columna que coincida"foo" , pero fallarán de una manera probablemente inesperada si no es así. Si, por ejemplo, utiliza cualquiera de ellos para buscar la columna inexistente "bar", terminará con una tabla de datos de fila cero.

Como consecuencia, son realmente más adecuados para uso interactivo donde uno podría, por ejemplo, querer mostrar una tabla de datos menos cualquier columna con nombres que contengan la subcadena "foo". Para fines de programación (o si realmente desea eliminar las columnas df3en lugar de una copia), los métodos 1, 2a y 2b son realmente las mejores opciones.

# Method 4:
df3[, .SD, .SDcols = !patterns("^foo$")]

Por último, hay enfoques que utilizan with=FALSE, aunque data.tablegradualmente se está alejando del uso de este argumento, por lo que ahora se desaconseja cuando se puede evitar; se muestra aquí para que sepa que la opción existe en caso de que realmente la necesite:

# Method 5a (like Method 3)
df3[, !"foo", with=FALSE] 
# Method 5b (like Method 4)
df3[, !grep("^foo$", names(df3)), with=FALSE]
# Method 5b (another like Method 4)
df3[, !grepl("^foo$", names(df3)), with=FALSE]
Josh O'Brien avatar Feb 08 '2012 22:02 Josh O'Brien

También puedes usar setpara esto, lo que evita la sobrecarga de [.data.tablelos bucles in:

dt <- data.table( a=letters, b=LETTERS, c=seq(26), d=letters, e=letters )
set( dt, j=c(1L,3L,5L), value=NULL )
> dt[1:5]
   b d
1: A a
2: B b
3: C c
4: D d
5: E e

Si desea hacerlo por nombre de columna, which(colnames(dt) %in% c("a","c","e"))debería funcionar para j.

Ari B. Friedman avatar Oct 21 '2013 20:10 Ari B. Friedman