如何在R中合并两个大数据集并生成一个带有不同重复值的新列

6

我有一个问题让我很困惑,真的需要你的帮助。简化后的问题是:

d1<-data.table(v1=c("a","b","c","d","d","b","a","c","a","d","b","a"),
                    v2=(seq(1:12)),V3=rep(1:4,times=3))

d2<-data.table(v1=c("a","b","c","d"),v3=c(3,2,1,4),v4=c("y","x","t","e"))

这将产生两个数据集:
    D1:     
    v1 v2 V3
 1:  a  1  1
 2:  b  2  2
 3:  c  3  3
 4:  d  4  4
 5:  d  5  1
 6:  b  6  2
 7:  a  7  3
 8:  c  8  4
 9:  a  9  1
10:  d 10  2
11:  b 11  3
12:  a 12  4

> d2
   v1 v3 v4
1:  a  3  y
2:  b  2  x
3:  c  1  t
4:  d  4  e

您可以看到v1和v3中的元素是相同的。现在我想通过在D1中创建一个新列来连接两个数据集,该新列返回d2中与v1和v3匹配的V4的值,希望能得到以下输出:

>

 d3
    v1 v2 V3 V4
 1:  a  1  1 na
 2:  b  2  2  x
 3:  c  3  3 na
 4:  d  4  4  e
 5:  d  5  1 na
 6:  b  6  2  x
 7:  a  7  3  y
 8:  c  8  4 na
 9:  a  9  1 na
10:  d 10  2 na
11:  b 11  3 na
12:  a 12  4 na

我正在使用的实际数据量相对较大,类似于将113MB的数据与23MB的数据合并。我尝试使用for循环来解决这个问题,但是由于数据太长,完成任务需要很长时间。我还尝试了mergesqldf,但两者都无法完成任务。你能否帮我解决这个问题?非常感谢!


sqldf 花费时间过长的原因可能是您没有在连接列上放置索引。主页上有示例,也有很多关于示例的问题在 SO 上。 - G. Grothendieck
非常感谢您提供的信息。 - sxgn
1个回答

8
我会这样做:
setkey(d1, v1, V3) 
d1[d2, v4 := v4][]
  • 对于形如 x[i] 的连接,需要设置 x 的键。 i 可以有或没有键设置。因此,我们在这里将 d1 的键设置为列 v1V3

  • 接下来,我们执行一个连接 d1[d2],它会找到与 d1 的键列匹配的 d2 的每一行,并返回连接结果。我们不是在寻找那个精确的结果。相反,我们想要添加一个新列,在该列中每个匹配的行的值都来自于 d2v4,否则就是NA。为此,我们利用了 data.table 的子赋值引用功能。在连接 ix 时,我们仍然可以在 j 中提供一个表达式,并引用 i 的列。您还可以将它们称为 i.v4(如果在 xi 中存在相同名称的列,则通常使用此方法)。

  • := 通过引用添加/更新列。 := 的左侧是我们要在此创建的列名,右侧的 v4 是我们要从中分配值的值(在这里,它是来自 d2 的列)。因此,对于每个匹配的行,我们通过引用(就地修改,意味着不会复制)将 d2v4 分配给 d1 的新列(我们命名为)v4,而那些没有匹配的行则会获得默认值NA

  • 最后一个 [] 只是将输出打印到屏幕上,因为 := 以不可见方式返回结果。

希望这有助于理解这里正在发生什么。


1
非常感谢您详细的解释,它非常有效。再次感谢!!! - sxgn

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接