大家下午好,
我想通过引用将两个data.table
合并在一起,而不必记下我想要合并的所有变量。这是一个了解我需求的简单示例:
> set.seed(20170711)
> (a <- data.table(v_key=seq(1, 5), key="v_key"))
v_key
1: 1
2: 2
3: 3
4: 4
5: 5
> a_backup <- copy(a)
> (b <- data.table(v_key=seq(1, 5), v1=runif(5), v2=runif(5), v3=runif(5), key="v_key"))
v_key v1 v2 v3
1: 1 0.141804303 0.1311052 0.354798849
2: 2 0.425955903 0.3635612 0.950234261
3: 3 0.001070379 0.4615936 0.359660693
4: 4 0.453054854 0.5768500 0.008470552
5: 5 0.951767837 0.1649903 0.565894298
我想通过引用将b
的每一列复制到a
,而不指定列名。
我可以执行以下操作,但这样会无缘无故地复制对象,从而降低程序的性能并增加所需的RAM:
> (a <- a[b])
v_key v1 v2 v3
1: 1 0.141804303 0.1311052 0.354798849
2: 2 0.425955903 0.3635612 0.950234261
3: 3 0.001070379 0.4615936 0.359660693
4: 4 0.453054854 0.5768500 0.008470552
5: 5 0.951767837 0.1649903 0.565894298
另一个选项(没有无用的副本)将指定b
的每一列的名称,从而产生以下结果:
> a <- copy(a_backup)
> a[b, `:=`(
+ v1=v1,
+ v2=v2,
+ v3=v3
+ )][]
v_key v1 v2 v3
1: 1 0.141804303 0.1311052 0.354798849
2: 2 0.425955903 0.3635612 0.950234261
3: 3 0.001070379 0.4615936 0.359660693
4: 4 0.453054854 0.5768500 0.008470552
5: 5 0.951767837 0.1649903 0.565894298
简而言之,我希望能够提高第二个示例的效率(没有无用的副本),而无需在b
中指定每个列名。
我想我可以找到一种使用colnames()
和get()
函数组合的方法,但我想知道是否有更简洁的方法来实现它,语法非常重要我
感谢大家的贡献!
JPL
答案 0 :(得分:3)
正如您所写,colnames
和mget
的组合可以帮助您。
考虑一下:
# retrieve the column names from b - without the key ('v_key')
thecols = setdiff(colnames(b), key(b))
# assign them to a
a[b, (thecols) := mget(thecols)]
这不是太糟糕了,是吗?
此外,我不认为目前使用data.table
实现了另一种语法。但我很高兴被证明是错误的:)
答案 1 :(得分:0)
回顾related question here作为一个例子,在这种情况下我总是喜欢Reduce
:
# provide list of DTs to be merged
arbitrary.dts <- list(...)
a <- Reduce(function(x, y) merge(x, y, all=T,
by=c("v_key")), arbitrary.dts, accumulate=F)
只有一个想法(我总是喜欢从基本功能开始)。我确信现在有一个更加流畅的data.table
答案。