web-dev-qa-db-fra.com

Supprimer plusieurs colonnes de R data.table avec paramètre pour les colonnes à supprimer

J'essaie de manipuler un certain nombre de data.tables de manière similaire et j'aimerais écrire une fonction pour accomplir cela. Je voudrais passer un paramètre contenant une liste de colonnes dans lesquelles les opérations seraient effectuées. Cela fonctionne bien lorsque la déclaration vectorielle de colonnes est le côté gauche de l'opérateur: =, mais pas si elle est déclarée plus tôt (ou passée dans la fonction). Le code suivant montre le problème.

dt = data.table(a = letters, b = 1:2, c=1:13)
colsToDelete = c('b', 'c')
dt[,colsToDelete := NULL] # doesn't work but I don't understand why not.
dt[,c('b', 'c') := NULL] # works fine, but doesn't allow passing in of columns

L'erreur est "Ajouter une nouvelle colonne 'colsToDelete' puis assigner NULL (le supprimer)." Donc, clairement, il interprète "colsToDelete" comme un nouveau nom de colonne.

Le même problème se produit lorsque vous faites quelque chose dans ce sens

dt[, colNames := lapply(.SD, adjustValue, y=factor), .SDcols = colNames]

Je connais R, mais je connais un peu mieux certaines langues, alors c’est peut-être une question idiote.

27
user3704757

C'est essentiellement parce que nous autorisons les symboles sur LHS de := à ajouter de nouvelles colonnes, par souci de commodité: ex: DT[, col := val]. Donc, afin de distinguer col étant lui-même le nom de ce qui est stocké dans col étant les noms de colonnes, nous vérifions si le LHS est une name ou une expression.

S'il s'agit d'une name, il ajoute la colonne avec le nom en tant que tel sur le LHS, et si expression, alors il sera évalué.

DT[, col := val] # col is the column name.

DT[, (col) := val]  # col gets evaluated and replaced with its value
DT[, c(col) := val] # same as above

L'idiome préféré est: dt[, (colsToDelete) := NULL]

HTH

40
Arun

Pour prolonger la réponse précédente, vous pouvez supprimer des colonnes par référence à:

# delete columns 10 to 15
dt[ , (10:15) := NULL ]

ou 

# delete columns 3, 5 and 10 to 15
dt[ , (c(3,5,10:15)) := NULL ]
4
rafa.pereira

Je suis surpris qu'aucune réponse fournie n'utilise la fonction set().

set(DT, , colsToDelete, NULL)

Cela devrait être le plus facile.

1
Jfly