Comment supprimer une colonne par 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 object data.table , il est impossible 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 object data.table , cela ne fonctionne plus.

L’une des opérations suivantes supprimera la colonne foo du 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 la colonne "foo" ), vous devriez 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 voulez pas de colonnes avec des noms comme "fool" et "buffoon" (c’est-à-dire ceux contenant foo tant que sous-chaîne) doit également être mis en correspondance et supprimé.)

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

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

En conséquence, ils sont vraiment mieux adaptés à un usage interactif où l’on pourrait, par exemple, afficher un data.table moins les colonnes dont le nom contient la sous-chaîne "foo" . Pour les besoins de la programmation (ou si vous voulez réellement supprimer les colonnes de df3 plutôt que d’une copie de celle-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] 

Vous pouvez également set cet utilisateur, 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] bd 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 .

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

 DT$col = NULL 

Fonctionne rapidement et pour autant que je puisse voir ne cause aucun problème.

UPDATE: pas la meilleure méthode si votre DT est très volumineux, car l’utilisation de l’opérateur $<- conduira à la copie d'objects. Donc, mieux utiliser:

 DT[, col:=NULL] 

Option très simple au cas où vous auriez plusieurs colonnes à supprimer dans une table de données et que vous souhaitiez éviter de taper tous les noms de colonne #careadviced

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

Cela supprimera les colonnes basées sur le numéro de colonne à la place.

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

Supposons que votre dt a des colonnes col1 , col2 , col3 , col4 , col5 , coln .

Pour supprimer un sous-ensemble d’entre eux:

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

Voici une manière de définir un nombre de colonnes sur NULL, étant donné que leur nom de colonne est une fonction pour votre usage 🙂

deleteColsFromDataTable <- function (train, toDeleteColNames) {

  for (myNm in toDeleteColNames) train <- train [,(myNm):=NULL,with=F] return (train) 

}

 DT[,c:=NULL] # remove column c 

Pour un data.table, l’affectation de la colonne à NULL le supprime:

 DT[,c("col1", "col1", "col2", "col2")] <- NULL ^ |---- Notice the extra comma if DT is a data.table 

... qui est l'équivalent de:

 DT$col1 <- NULL DT$col2 <- NULL DT$col3 <- NULL DT$col4 <- NULL 

L'équivalent pour un data.frame est:

 DF[c("col1", "col1", "col2", "col2")] <- NULL ^ |---- Notice the missing comma if DF is a data.frame 

Q. Pourquoi existe-t-il une virgule dans la version de data.table et aucune virgule dans la version de data.frame?

A. Comme data.frames est stocké sous la forme d'une liste de colonnes, vous pouvez ignorer la virgule. Vous pouvez également l'append, mais vous devrez alors les assigner à une liste de NULL s, DF[, c("col1", "col2", "col3")] <- list(NULL) .