2012-12-02 60 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