首页 > 解决方案 > 如何使用 *alternative* 列合并 R 中的数据框

问题描述

我正在尝试在 R 中合并 2 个数据框,但我有两个不同类型的 ID 变量的不同列。有时,一行将具有其中一个列的值,而另一列则没有。我想同时考虑它们,因此如果一帧缺少其中一列的值,则将使用另一列。

> df1 <- data.frame(first = c('a', 'b', NA),  second = c(NA, 'q', 'r'))
> df1
first second
1     a   <NA>
2     b      q
3  <NA>      r

> df2 <- data.frame(first = c('a', NA, 'c'),  second = c('p', 'q', NA))
> df2
  first second
1     a      p
2  <NA>      q
3     c   <NA>

我想合并这两个数据框并得到 2 行:

在这种情况下,忽略 NA 并且不“匹配”很重要。

我可以接近:

> merge(df1,df2, by='first', incomparables = c(NA))
  first second.x second.y
1     a     <NA>        p
> merge(df1,df2, by='second', incomparables = c(NA))
  second first.x first.y
1      q       b    <NA>

但是我不能将这两个数据框 rbind 在一起,因为它们有不同的列名,而且这似乎不是“R”的方式(在不久的将来,我会有第 3、第 4 甚至第 5 ID 类型)。

有没有更笨拙的方法来做到这一点?

编辑:理想情况下,输出将如下所示:

> df3 <- data.frame(first = c('a', 'b'), second = c('p','q'))
> df3
  first second
1     a      p
2     b      q

标签: rdataframejoinmerge

解决方案


使用sqldf我们可以做的,就像在 SQL 中一样,我们可以在连接条件之间交替使用OR

library(sqldf)
df <- sqldf("select a.*, b.*
               from df1 a
               join df2 b
                    ON a.first = b.first
                    OR a.second = b.second")


library(dplyr)
       #If value in first is NA i.e. is.na(first) is TRUE then use first..3 value's else use first value's and the same for second
df %>% mutate(first = ifelse(is.na(first), first..3, first),
              second = ifelse(is.na(second), second..4, second)) %>% 
       #Discard first..3 and second..4 since we no longer need them    
       select(-first..3, -second..4) 

  first second
1     a      p
2     b      q

推荐阅读