2012-12-02 98 views
5

我想做一個簡單的循環使用data.table。我有20個二分(0,1)變量(從VAR_1到var_20),我想這個做一個循環:一個簡單的循環與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] 

我的主要問題是,我不知道如何指定我(即VAR_1 = = 1,var_2 == 2 ...)使用循環。 下面一個簡單的例子:

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] 

有關如何使用一個循環做到這一點任何想法? 謝謝!

回答

4

要利用data.table類,最好設置key。

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

謝謝。你知道怎麼做newvar:= 1L從1增加到變量的數量(例如,varvar的newvar應該等於2,var_3的3應該等於,等等)。也有可能某些變量同時具有值​​1,在這種情況下,我只想估算更大的值(例如,一個案例var_1 = 1,var_3 = 1,我想得到newvar = 3)。 – sdaza

+0

上面的代碼應該這樣做。我會對重複設置鍵的性能感興趣,而不是對大數據進行順序掃描或單一矢量掃描。表 – mnel

+0

@WojciechSobala通常最好是設置鍵,但setkey必須在排序過程中讀取列(掃描)中的每個值它。因此,在單個掃描一個列的單個值的特殊情況下,矢量掃描應該比setkey + join更快。值得測試,但我還沒有測試過自己。 –

4

這樣的事情會起作用。

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

它的工作,謝謝! – sdaza