将数据表匹配五列以更改另一列中的值

时间:2016-08-27 01:32:00

标签: r amazon-web-services parallel-processing data.table

我有Ubuntu 16.04并在终端中运行R. 我正在处理大数据表,一个有7500万行和11列(dt1),另一个有700万行和7列(dt2)。所有值都是数字。两个表都有'id'列'。我需要找到第一个中具有相同值的五列作为第二个中的五列的所有行,并将这些行的第一个数据表'id'值更改为第二个数据表中的一行。在两个数据表中,比较列具有相同的名称,假设它们是V1,V2,V3,V4和V5。我已将第二个数据表转换为数据帧格式,因此我可以使用其“id”作为索引。我已经尝试了1000行,然后花了40分钟。

for (i in 1:1000) {
    dt1[(V1==dt2[i,V1] & V2==dt2[i,V2] &
         V3==dt2[i,V3] & V4==dt2[i,V4] &
         V5==dt2[i,V5]), id:=i]
}

我要将它并行化,但由于内存限制,我只能使用2或3个内核。显然这还不够。有没有快速有效的方法在我的家庭comp上做到这一点?如果要在AWS上执行此操作,那么哪种技巧有用?特别是,我可以同时使用多少个核心?

1 个答案:

答案 0 :(得分:4)

在R中,最好尽可能避免循环,因为它们通常比替代的矢量化解决方案慢得多。

此操作可以使用data.table连接完成。基本上,当你运行

dt1[dt2];

您正在两个data.tables之间执行右连接。 dt1的预设键列确定要加入的列。如果dt1没有预设密钥,则操作失败。但是您可以指定on参数来手动选择关键列:

key <- paste0('V',1:5);
dt1[dt2,on=key];

(替代方法当然是使用setkey()setkeyv()预设密钥。)

上述操作实际上只会返回一个包含来自dt1dt2的数据的合并表,这不是您想要的。但是我们可以使用data.table索引函数的j参数和:=就地赋值语法来将id dt2列分配给{ {1}} id列。由于我们存在名称冲突,因此我们必须使用dt1来引用i.id的{​​{1}}列,而未修改的名称id仍然引用dt2id。这只是data.table提供的机制,用于消除冲突名称的歧义。因此,您正在寻找:

id

这是一个仅使用两个键列和几行数据的示例(为简单起见)。我还生成了包含一些不匹配行的键,只是为了证明不匹配的行将使操作不会触及它们的ID。

dt1