2012-12-02 21 views
5

Voglio fare un ciclo semplice usando data.table. Ho 20 (0,1) variabili dicotomiche (da var_1 a var_20) e mi piacerebbe fare un ciclo per questo:un semplice loop con data.table

dat[var_1==1, newvar:=1] 
dat[var_2==1, newvar:=2] 
dat[var_3==1, newvar:=3] 
... 
dat[var_20==1, newvar:=21] 

Il mio problema principale è che non so come specificare i (cioè var_1 = = 1, var_2 == 2 ...) utilizzando un ciclo. Qui di seguito un breve esempio:

var_1 <- c(1, rep(0,9)) 
var_2 <- c(0,1, rep(0,8)) 
var_3 <- c(0,0,1, rep(0,7)) 
dat <- data.table(var_1, var_2, var_3) 

dat[var_1==1, newvar:=1] 
dat[var_2==1, newvar:=2] 
dat[var_3==1, newvar:=3] 

Tutte le idee su come fare questo con un ciclo? Grazie!

risposta

4

Per sfruttare la classe data.table è meglio impostare la chiave.

dat[ ,newvar:= NA_integer_] 
for(i in ncol(dat)) { 
setkeyv(dat, names(dat)[i]) 
dat[J(1), newvar:=i] 
} 
+0

Grazie. Sai come fare newvar: = 1 L aumenta da 1 al numero di variabili (ad esempio, newvar dovrebbe essere uguale a 2 per var_2, 3 per var_3 e così via). È anche possibile che alcune variabili abbiano un valore 1 simultaneamente, in tal caso, vorrei imputare solo il valore più grande (ad esempio, un caso ha var_1 = 1 e var_3 = 1, vorrei ottenere newvar = 3). – sdaza

+0

Il codice sopra dovrebbe farlo. Sarei interessato all'esecuzione di ripetuti tasti di impostazione rispetto alle scansioni sequenziali ma vettoriali singole su grandi dati.tables – mnel

+0

@WojciechSobala Di solito è meglio impostare setkey ma setkey deve leggere ogni valore nella colonna (scansione) nel processo di ordinamento esso. Quindi nel caso speciale di una singola scansione per un singolo valore su una singola colonna, una scansione vettoriale dovrebbe essere più veloce di setkey + join. Vale la pena provare, non l'ho testato io stesso. –

4

Qualcosa di simile funzionerà.

nams <- names(dat) 
for(n in seq_along(nams)){ 
    nam <- nams[n] 
    char <- sprintf('%s==1',nam) 
    dat[eval(parse(text=char)), newvar := n] 
} 
dat 
var_1 var_2 var_3 newvar 
1:  1  0  0  1 
2:  0  1  0  2 
3:  0  0  1  3 
4:  0  0  0  NA 
5:  0  0  0  NA 
6:  0  0  0  NA 
7:  0  0  0  NA 
8:  0  0  0  NA 
9:  0  0  0  NA 
10: 0  0  0  NA 
+0

Ha funzionato, grazie! – sdaza