R dplyr full_join - 没有公共键,需要公共列混合在一起

Posted

技术标签:

【中文标题】R dplyr full_join - 没有公共键,需要公共列混合在一起【英文标题】:R dplyr full_join - no common key, need common columns to blend together 【发布时间】:2022-01-20 14:56:01 【问题描述】:

例如,我有这两个数据框:

dates = c('2020-11-19', '2020-11-20', '2020-11-21')
df1 <- data.frame(dates, area = c('paris', 'london', 'newyork'), 
                  rating = c(10, 5, 6),
                  rating2 = c(5, 6, 7))

df2 <- data.frame(dates, area = c('budapest', 'moscow', 'valencia'), 
                  rating = c(1, 2, 1))
> df1
       dates    area rating rating2
1 2020-11-19   paris     10       5
2 2020-11-20  london      5       6
3 2020-11-21 newyork      6       7
> df2
       dates     area rating
1 2020-11-19 budapest      1
2 2020-11-20   moscow      2
3 2020-11-21 valencia      1

使用 dplyr 执行外连接时:

df <- df1 %>%
  full_join(df2, by = c('dates', 'area'))

结果是这样的:

       dates     area rating.x rating2 rating.y
1 2020-11-19    paris       10       5       NA
2 2020-11-20   london        5       6       NA
3 2020-11-21  newyork        6       7       NA
4 2020-11-19 budapest       NA      NA        1
5 2020-11-20   moscow       NA      NA        2
6 2020-11-21 valencia       NA      NA        1

即来自两个数据框的评分列没有混合在一起,而是创建了两个单独的列。

我怎样才能得到这样的结果?

       dates     area rating   rating2 
1 2020-11-19    paris       10       5       
2 2020-11-20   london        5       6       
3 2020-11-21  newyork        6       7       
4 2020-11-19 budapest        1      NA        
5 2020-11-20   moscow        2      NA        
6 2020-11-21 valencia        1      NA        

感谢@kybazzi提供的解决方案,得到了想要的结果。

df <- df1 %>%
  bind_rows(df2)

跟进

作为后续问题,我想将以下内容加入到加入的数据框中:

df3 <- data.frame(dates, area = c('budapest', 'moscow', 'valencia'), 
                  rating2 = c(3, 2, 5))

用同样的方法,结果是这样的:

> df_final <- df %>%
+     bind_rows(df3)
> df_final
       dates     area rating rating2
1 2020-11-19    paris     10       5
2 2020-11-20   london      5       6
3 2020-11-21  newyork      6       7
4 2020-11-19 budapest      1      NA
5 2020-11-20   moscow      2      NA
6 2020-11-21 valencia      1      NA
7 2020-11-19 budapest     NA       3
8 2020-11-20   moscow     NA       2
9 2020-11-21 valencia     NA       5

我如何得到这样的结果:

       dates     area rating   rating2 
1 2020-11-19    paris       10       5       
2 2020-11-20   london        5       6       
3 2020-11-21  newyork        6       7       
4 2020-11-19 budapest        1       3        
5 2020-11-20   moscow        2       2        
6 2020-11-21 valencia        1       5

【问题讨论】:

两个数据框之间是否有任何共享​​>的键(例如城市名称)?看起来您可以为 df2 指定 rating2 = NA 并使用 rbind 来收工,而不是摆弄合并 可能重复***.com/questions/27167151/… 【参考方案1】:

您要查找的是dplyr::bind_rows(),它将保留常用列并为仅存在于其中一个数据框中的列填充NA

> bind_rows(df1, df2)
       dates     area rating rating2
1 2020-11-19    paris     10       5
2 2020-11-20   london      5       6
3 2020-11-21  newyork      6       7
4 2020-11-19 budapest      1      NA
5 2020-11-20   moscow      2      NA
6 2020-11-21 valencia      1      NA

请注意,您也可以继续使用full_join() - 但如果您不希望列被拆分,则必须确保将数据框之间的所有公共列都包含为键:

> full_join(
+   df1, df2,
+   by = c("dates", "area", "rating")
+ )
       dates     area rating rating2
1 2020-11-19    paris     10       5
2 2020-11-20   london      5       6
3 2020-11-21  newyork      6       7
4 2020-11-19 budapest      1      NA
5 2020-11-20   moscow      2      NA
6 2020-11-21 valencia      1      NA

dplyr joins 的文档提到:

输出列包括所有x 列和所有y 列。如果xy 中的列具有相同的名称(并且未包含在by 中),则添加后缀以消除歧义。

您也可以通过不指定 by 来避免此问题,在这种情况下 dplyr 将使用所有常用列。

> full_join(df1, df2)
Joining, by = c("dates", "area", "rating")
       dates     area rating rating2
1 2020-11-19    paris     10       5
2 2020-11-20   london      5       6
3 2020-11-21  newyork      6       7
4 2020-11-19 budapest      1      NA
5 2020-11-20   moscow      2      NA
6 2020-11-21 valencia      1      NA

据我所知,这两种方法都适合您的用例。事实上,我相信full_join() 相对于bind_rows() 的实际优势正是您希望在此处避免的这种行为,即拆分不是键的列。

【讨论】:

对于找不到它的人,bind_rows 函数来自dplyr 包! @kybazzi 始终确保在您的答案中包含所有必要的库。

以上是关于R dplyr full_join - 没有公共键,需要公共列混合在一起的主要内容,如果未能解决你的问题,请参考以下文章

R语言dplyr包进行dataframe的连接(inner_joinleft_joinright_joinfull_joinsemi_joinanti_join)操作实战

full_join() r 中分段/批次中的两个数据帧

您如何保留原始列以在 r 中两个数据库的 full_join() 中进行比较

R 两个dataframe其中一列内容相同,但是顺序不同,如何合并?

如何使用 dplyr 将累积列添加到 R 数据框?

r/dplyr:在 UDF 中使用动态命名的变量