2014-11-03 34 views
3

我有个问题让我发狂,真的需要你的帮助。 简化的问题是:如何合并两个大型数据集,同时在r中生成具有不同重复值的新列

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 V4的值相匹配这两个指数V1和V3的是,我希望我能得到的输出看起来像这样:

> 

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 

的我使用的实际数据的大小相对非常大。这是像23MB的联合113MB数据。我试图使用for循环来解决这个问题,因为数据太长了,需要很长时间才能完成任务。我也试过mergesqldf,但他们都没有完成这项工作。你能帮我解决这个问题吗?非常感谢你!

+0

sqldf花了这么长时间的原因可能是您没有在连接列上放置索引。在主页上有一些例子,并且有很多关于例子的问题。 – 2014-11-03 22:28:15

+0

非常感谢信息 – sxgn 2014-11-04 09:59:41

回答

6

我会做这样的:

setkey(d1, v1, V3) 
d1[d2, v4 := v4][] 
  • 对于加盟的形式x[i]的,键被设置x需求。 i可能有也可能没有密钥集。所以我们在这里将d1的密钥设置为v1V3列。

  • 接下来,我们执行加入d1[d2],其中d2的每一行都找到与d1的键列匹配的行并返回连接结果。我们并不是完全在寻找那个结果。我们希望添加一个新列,其中每个匹配行从d2v4和其他NA获得值。为此,我们使用data.table的通过引用功能进行的子分配。在加入ix时,我们仍然可以在j中提供表达式,并参考i的列。您也可以将它们称为i.v4(通常在xi中都有相同名称的列时使用)。

  • :=通过引用添加/更新列。 :=的LHS是我们要在此处创建的列名称,RHS v4是我们要分配的值(这里是d2的列)。因此,对于每个匹配行,我们将d2v4分配到d1的新列(我们命名为)v4通过引用(in-place,意思是没有制作副本),而那些没有匹配的行将获得默认值NA

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

希望这有助于了解这里发生了什么。

+0

+1的解释。 – akrun 2014-11-04 09:22:02

+0

非常感谢您的详细解释,它工作得非常好。再次感谢!!! – sxgn 2014-11-04 10:03:18

相关问题