3

假设我有以下数据表R

L3 <- LETTERS[1:3]
(d <- data.table(cbind(x = 1, y = 1:10), fac = sample(L3, 10, replace = TRUE)))
vecfx=c(5.3,2.8)

我想计算两个新变量,dot1它们dot2是:

d[,dot1:=5.3*x]
d[,dot2:=2.8*y] 

但我不想以这种方式计算它们,因为这是对我的问题的一种放松。在我最初的问题中,vecfx由 12 个元素组成,我的数据表有 2 列,所以我想避免写那 2 次。

我试过这个:vecfx*d[,list(x,y)]但我没有得到想要的结果(看起来产品是按行而不是按列完成的)。另外,我想在我的数据表中创建这两个新变量d

当您想要在R.

任何帮助表示赞赏。

4

2 回答 2

8

更新:在v1.8.11中,现在实现了FR #2077set() -现在可以通过引用添加列,. 来自新闻

set()现在可以通过引用添加新列。例如,set(DT, i=3:5, j="bla", 5L)等价于DT[3:5, bla := 5L]。这是FR #2077。添加了测试。

然后可以做的事情(正如@MatthewDowle在评论下建议的那样):

for (j in seq_along(vecfx)) 
    set(d, i=NULL, j=paste0("dot", j), vecfx[j]*d[[j]])

我想你正在寻找?set. 请注意,set()也通过引用添加并且非常快!从以下粘贴相关部分?set

由于[.data.table检查参数的存在和类型(例如)会产生开销,因此set()通过引用以低开销提供直接(但不太灵活)赋值,适合在 for 循环内使用。请参阅示例。:=set()因为:=旨在与i大型数据集上的单个查询结合使用更灵活。

for (j in seq_along(vecfx)) 
    set(d, i=NULL, j=j, vecfx[j]*d[[j]])
      x    y fac
 1: 5.3  2.8   B
 2: 5.3  5.6   C
 3: 5.3  8.4   C
 4: 5.3 11.2   C
 5: 5.3 14.0   B
 6: 5.3 16.8   B
 7: 5.3 19.6   C
 8: 5.3 22.4   C
 9: 5.3 25.2   C
10: 5.3 28.0   C

只需提供正确的索引即可set

于 2013-09-24T20:03:20.850 回答
8

阿伦的回答很好。

接受多个项目的 LHS 和 RHS:=所以另一种方法是:

d[,paste0("dot",1:2):=mapply("*",vecfx,list(x,y),SIMPLIFY=FALSE)]
d
    x  y fac dot1 dot2
 1: 1  1   C  5.3  2.8
 2: 1  2   B  5.3  5.6
 3: 1  3   C  5.3  8.4
 4: 1  4   C  5.3 11.2
 5: 1  5   B  5.3 14.0
 6: 1  6   A  5.3 16.8
 7: 1  7   A  5.3 19.6
 8: 1  8   B  5.3 22.4
 9: 1  9   A  5.3 25.2
10: 1 10   A  5.3 28.0

也许有比这更好的方法。我认为 Arunfor应该更快,并且可能更容易阅读。

于 2013-09-24T20:15:51.873 回答