【发布时间】:2015-03-28 18:52:20
【问题描述】:
好的,我有一个使用 data.frames 构建的复杂函数,为了加快它的速度,我转向了 data.table。我对此完全陌生,所以我很困惑。无论如何,我已经为我想做的事情做了一个简单得多的玩具示例,但我无法弄清楚如何将其转换为 data.table 格式。下面是data.frame形式的例子:
rows <- 10
data1 <- data.frame( id =1:rows,
a = seq(0.2, 0.55, length.out = rows),
b = seq(0.35, 0.7, length.out = rows),
c = seq(0.4, 0.83, length.out = rows),
d = seq(0.6, 0.87, length.out = rows),
e = seq(0.7, 0.99, length.out = rows),
f = seq(0.52, 0.90, length.out = rows)
)
DT1 <- data.table(data1) #for later
data2 <- data.frame( id =3:1,
a = rep(3, 3),
d = rep(2, 3),
f = rep(1, 3)
)
m.names <- c("a", "d", "f")
data1[match(data2$id, data1$id),m.names] <- data1[match(data2$id, data1$id),m.names] + data2[match(data2$id, data1$id),m.names]
所以请注意,在最后一步中,我希望在预先存在的数字和新数据之间执行加法,并将其向量化到多个列中。
在 data.table 格式中,我只做到了这一点:
DT1[id %in% data2$id, m.names, with=FALSE]
这会选择我想要添加的值,但之后我就迷路了。我将不胜感激!
编辑:
好的,我已经弄清楚了其中的一部分 - 我可以使用上面的最后一行代码来实现矢量化加法部分,使用 data2 来存储添加的值,如下所示:
data2[,m.names] <- data2[,m.names] + data.frame(DT1[id %in% data2$id, m.names, with=FALSE])
即使有 250 万行(在 DT1 中)和 data2 中的 10,000 行和 6 个匹配列,这也只需要 0.004 秒,但我仍然需要将新的 data2 分配给数据 1 中适当的动态分配列
【问题讨论】:
-
如果您不介意手动调用列名,可以进行简单的二进制连接,例如
setkey(setDT(data1), id) ; data1[data2, ":="(a = a + i.a,d = d + i.d,f = f + i.f)] -
@DavidArenburg 您的解决方案更好、更紧凑。
-
@akrun 你的解决方案更通用,所以我会把它留在那里,让 OP 决定
-
感谢大卫,但在我的真实数据中不起作用。我不能使用 a,d,f 我需要使用 m.names[1] 因为列数可能会有所不同 - 使用 m.names[] 构造似乎不起作用..第二点在玩具数据中匹配版本出现得更快(并且在我使用 fmatch 的真实代码中)
-
好的,我找到了一种通过矢量化进行添加的快速方法 - 请参阅我的编辑 - 但我仍然需要使用分配的变量列名将结果打包回 data1 ??
标签: r data.table