2017-09-03 65 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 
相关问题