合并每个数据框的一列中的值对

时间:2015-02-14 22:50:24

标签: r merge dataframe

我正在尝试将两个数据帧与不同长度和行的列合并。为了给出DF1的确切概念:

     ID     year    freq1   mun    
       1    2005    2     61137
       1    2006    1     61383
       2    2005    3     14520
       2    2006    2     14604
       4    2005    3     101423
       4    2006    1     102257
       6    2005    0     39039
       6    2006    1     39346

而DF2是:

      ID        year    freq2   mun
       1        2004    5     60857
       1        2005    3     61137
       2        2004    4     14278
       2        2005    4     14520
       3        2004    2     22563
       3        2005    0     22635
       4        2004    6     101015
       4        2005    4     101423
       5        2004    6     61152
       5        2005    3     61932
       6        2004    4     38456
       6        2005    3     39039

正如您所看到的,年份和市政变量都有所不同,只有一个共同的条目。所以我想要实现的是合并freq1和freq2列的ID。然而,诀窍是DF1应该以这样的方式获得优先权(左合并?),而mun变量是从DF1中选择的变量。 期望的输出:

      ID    year    freq1   mun    freq2
       1    2005    2     61137    5
       1    2006    1     61383    3
       2    2005    3     14520    4
       2    2006    2     14604    4
       4    2005    3     101423   6
       4    2006    1     102257   4
       6    2005    0     39039    4
       6    2006    1     39346    3

以及DF2以其他方式优先考虑以下方式:

      ID        year    freq2   mun   freq1
       1        2004    5     60857   2
       1        2005    3     61137   1
       2        2004    4     14278   3
       2        2005    4     14520   2
       3        2004    2     22563   0
       3        2005    0     22635   0
       4        2004    6     101015  3
       4        2005    4     101423  1
       5        2004    6     61152   0
       5        2005    3     61932   0
       6        2004    4     38456   0
       6        2005    3     39039   1

我已经尝试删除year和mun列并根据公共ID合并freq1和freq2但是它只为我提供了多个重复条目。有什么建议吗?

2 个答案:

答案 0 :(得分:2)

您似乎正在尝试按照显示的顺序匹配数据框中的ID对。

仅在ID列上匹配将导致形成交叉产品,为ID == 1提供四行,这就是我假设您的意思是"多个重复条目。& #34;

要合并ID值对,您需要消除个别值的歧义,因此merge会将ID中的第一个df1值与第一个ID合并1}} df2中的值,以及第二个ID值的类似值。

这种歧义消除可以通过添加另一列来完成,该列为所看到的ID值的数量添加一个计数器。 seq_along计数,ave适用于"等级" ID

df1$ID2 <- ave(df1$ID, df1$ID, FUN=seq_along)
df2$ID2 <- ave(df2$ID, df2$ID, FUN=seq_along)

这是新df1。同样修改了df2

> df1
  ID year freq1    mun ID2
1  1 2005     2  61137   1
2  1 2006     1  61383   2
3  2 2005     3  14520   1
4  2 2006     2  14604   2
5  4 2005     3 101423   1
6  4 2006     1 102257   2
7  6 2005     0  39039   1
8  6 2006     1  39346   2

这些现在适合传递给merge以获得您想要的双方。从每一侧删除未使用的列可防止合并获取您不想要的数据:

> merge(df1, df2[-c(2,4)], by=c('ID', 'ID2'), all.x=T)[-2]
  ID year freq1    mun freq2
1  1 2005     2  61137     5
2  1 2006     1  61383     3
3  2 2005     3  14520     4
4  2 2006     2  14604     4
5  4 2005     3 101423     6
6  4 2006     1 102257     4
7  6 2005     0  39039     4
8  6 2006     1  39346     3
> merge(df1[-c(2,4)], df2, by=c('ID', 'ID2'), all.y=T)[-2]
   ID freq1 year freq2    mun
1   1     2 2004     5  60857
2   1     1 2005     3  61137
3   2     3 2004     4  14278
4   2     2 2005     4  14520
5   3    NA 2004     2  22563
6   3    NA 2005     0  22635
7   4     3 2004     6 101015
8   4     1 2005     4 101423
9   5    NA 2004     6  61152
10  5    NA 2005     3  61932
11  6     0 2004     4  38456
12  6     1 2005     3  39039

请注意,NA值用于没有匹配项的位置。如果真的合适,您可以用0值替换它们。

最后的[-2]会移除添加的列ID2

这是一种非常不寻常的合并方式。它取决于数据的顺序以及值,因此它看起来确实很脆弱。但我确实认为我已经抓住了你想要实现的目标。

答案 1 :(得分:1)

使用match函数查找DF1和DF2之间的相应行。请参阅下面的代码。

# Find rows in DF1 that matches rows in DF2, get "freq2" values from them. 
cbind(DF1, DF2[ match( DF1[,"year"], DF2[,"year"] ), "freq2" ])

# Find rows in DF1 that matches rows in DF2, get "freq2" values from them. 
cbind(DF2, DF1[ match( DF2[,"year"], DF1[,"year"] ), "freq1" ])