2014-07-05 3 views
23

Sto provando a manipolare un numero di data.tables in modi simili e vorrei scrivere una funzione per farlo. Vorrei passare in un parametro che contiene un elenco di colonne in cui verranno eseguite le operazioni. Funziona perfettamente quando la dichiarazione vettoriale di colonne è il lato sinistro dell'operatore: =, ma non se è dichiarata in precedenza (o passata alla funzione). Il codice seguente mostra il problema.Rimozione di più colonne da R data.table con parametro per colonne da rimuovere

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'errore viene "Aggiunta nuova colonna 'colsToDelete' assegnando NULL (eliminandolo)." Quindi, chiaramente, interpreta 'colsToDelete' come un nuovo nome di colonna.

Lo stesso problema si verifica quando si fa qualcosa in questo senso

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

ho di nuovo da R, ma un po 'più esperto con alcune altre lingue, quindi questo potrebbe essere una domanda stupida.

risposta

33

Fondamentalmente perché consentiamo ai simboli su LHS di := di aggiungere nuove colonne, per comodità: es: DT[, col := val]. Pertanto, al fine di distinguere col come nome da qualunque cosa è memorizzata in col come nome di colonna, controlliamo se il LHS è un name o un expression.

Se è un name, aggiunge la colonna con il nome come tale sul LHS, e se expression, quindi viene valutato.

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'idioma preferito è: dt[, (colsToDelete) := NULL]

HTH

3

Per estendere il precedente risposta, è possibile eliminare le colonne facendo riferimento facendo:

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

o

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