web-dev-qa-db-fra.com

Comment supprimez-vous une colonne par son nom dans data.table?

Pour me débarrasser d'une colonne nommée "foo" dans un data.frame, je peux faire:

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

Cependant, une fois que df est converti en un objet data.table, il n’ya aucun moyen de supprimer une colonne.

Exemple:

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))] 

Mais une fois converti en un objet data.table, cela ne fonctionne plus.

167
Maiasaura

L’un des éléments suivants supprimera la colonne foo du fichier 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 prend également en charge la syntaxe suivante:

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

cependant, si vous vouliez réellement supprimer la colonne "foo" de df3 (au lieu de simplement imprimer une vue de df3 moins colonne "foo"), vous voudriez vraiment utiliser la méthode 1 à la place.

(Notez que si vous utilisez une méthode reposant sur grep() ou grepl(), vous devez définir pattern="^foo$" plutôt que "foo", si vous ne souhaitez pas que les colonnes portant des noms comme "fool" et "buffoon" (c'est-à-dire contenant foo comme sous-chaîne) soient également appariées. et enlevé.)

Options moins sûres, parfait pour une utilisation interactive:

Les deux expressions suivantes fonctionneront également - si df3 contient une colonne correspondant à "foo"-, mais échouera de manière probablement inattendue si ce n’est pas le cas. Si, par exemple, vous utilisez l'un d'eux pour rechercher la colonne inexistante "bar", vous vous retrouverez avec un fichier data.table à zéro ligne.

Par conséquent, ils conviennent parfaitement à une utilisation interactive, par exemple si vous souhaitez afficher un fichier data.table moins les colonnes dont le nom contient la sous-chaîne "foo". Pour des raisons de programmation (ou si vous souhaitez réellement supprimer les colonnes de df3 plutôt que d'une copie de celles-ci), les méthodes 1, 2a et 2b sont vraiment les meilleures options.

# Method 4a:
df3[, -grep("^foo$", colnames(df3)), with=FALSE]

# Method 4b: 
df3[, !grepl("^foo$", colnames(df3)), with=FALSE]
242
Josh O'Brien

Vous pouvez également utiliser set pour cela, ce qui évite la surcharge de [.data.table dans les boucles:

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 vous voulez le faire par nom de colonne, which(colnames(dt) %in% c("a","c","e")) devrait fonctionner pour j.

29
Ari B. Friedman

Je le fais simplement dans le genre de trame de données:

DT$col = NULL

Travaille vite et, autant que je sache, cela ne pose aucun problème.

UPDATE: pas la meilleure méthode si votre DT est très volumineux, car l’opérateur $<- entraînerait la copie d’objets. Donc mieux utiliser:

DT[, col:=NULL]
16
msp

Option très simple dans le cas où vous avez plusieurs colonnes individuelles à supprimer dans une table de données et que vous souhaitez éviter de saisir tous les noms de colonne #careadviced

dt <- dt[, -c(1,4,6,17,83,104), with =F]

Cela supprimera les colonnes en fonction du numéro de colonne.

Ce n'est évidemment pas aussi efficace car il contourne les avantages de data.table, mais si vous travaillez avec moins de 500 000 lignes, cela fonctionne bien.

4
SJDS

Supposons que votre dt ait les colonnes col1, col2, col3, col4, col5, coln.

Pour en supprimer un sous-ensemble:

vx <- as.character(bquote(c(col1, col2, col3, coln)))[-1]
DT[, paste0(vx):=NULL]
0
Ricardo Paixao