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

Merging on pairs of values in one column of each data frame

我正在尝试合并两个具有不同长度列的数据框,rows.To给出 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

如您所见,year 和 mun 变量有些不同,并且只有一个公共条目。所以我想要实现的是合并关于 ID 的 freq1 和 freq2 列。然而,诀窍在于 DF1 应该优先考虑(左合并?),这样 year 和 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,但它只为我提供了多个重复条目。有什么建议吗?

使用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" ])

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

单独匹配 ID 列将导致形成叉积,为 ID == 1 提供四行,这就是我假设你所说的 "multiple duplicate entries."

要合并成对的 ID 值,您需要消除各个值的歧义,因此 mergedf1 中的第一个 ID 值与第一个值合并ID 值在 df2 中,第二个 ID 值也类似。

可以通过添加另一列来消除歧义,这会为看到的 ID 值的数量添加一个计数器。 seq_along算,ave适用于ID的"levels":

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

这是新的 df1df2同样修改

> 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

这是一种相当不寻常的合并方式。除了值之外,它还取决于数据的顺序,因此它看起来确实很脆弱。但我确实认为我已经抓住了你想要完成的事情。