2017-09-03 66 views
2

我在思考如何通過引用高效地分配data.table的單個單元格時遇到問題。每一列(除了id)都表明該科目在特定的日子處於狀態。向列分配R data.table單元格,列中行數不同

爲了便於說明,將每行切換的列存儲在單獨的列表或向量中。以下for循環可以完成這項工作,但實際數據非常大(因此也可以通過引用進行分配),而更原生的解決方案將是理想的。

dt = data.table(id = letters[1:5], 
       `1`=0,`2`=0,`3`=0) 

d = c(3,2,1,2,3) 

for (i in 1:nrow(dt)) { 
    print(d[i]) 
    dt[i,1+d[i] := 1] 
} 

print(dt) 
# id 1 2 3 
# 1: a 0 0 1 
# 2: b 0 1 0 
# 3: c 1 0 0 
# 4: d 0 1 0 
# 5: e 0 0 1 

所有我嘗試使用.SD或.I失敗,也許有人可以指出我在正確的方向嗎?

例如

dt[,d[.I] := 1] 

回答

4

我會使用set:=在for循環用於代替列行:

for(i in seq_along(dt)[-1]){ 
    set(dt, NULL, i, 0 + (d == i - 1)) 
} 
dt 
# id 1 2 3 
# 1: a 0 0 1 
# 2: b 0 1 0 
# 3: c 1 0 0 
# 4: d 0 1 0 
# 5: e 0 0 1 
+1

注意'set'也是'data.table'中的'Reference by reference'操作符' – SymbolixAU

2

另一種方法是先從id s的data.table和狀態的向量,則重塑

dt <- data.table(id = letters[1:5], state = d) 
# id state 
# 1: a  3 
# 2: b  2 
# 3: c  1 
# 4: d  2 
# 5: e  3 

dcast(dt, id ~ state, fun.aggregate = length) 

# id 1 2 3 
# 1: a 0 0 1 
# 2: b 0 1 0 
# 3: c 1 0 0 
# 4: d 0 1 0 
# 5: e 0 0 1 
2

base R方法將是使用row/column IND ex

setDF(dt) 
dt[-1][cbind(seq_len(nrow(dt)), d)] <- 1 
dt 
# id 1 2 3 
#1 a 0 0 1 
#2 b 0 1 0 
#3 c 1 0 0 
#4 d 0 1 0 
#5 e 0 0 1 
相關問題