如何在 dplyr 中 Full Join 多个数据集(ncol 不匹配)

How to Full Join several datasets in dplyr (ncol do not match)

我有三个数据帧(d1、d2、d3),其中 ncol 和 nrow 在数据集中不匹配。

我想按公共列合并这些数据集,同时保留所有唯一的列和行。

我相信这意味着我需要一个完全连接,我已经尝试使用下面的示例代码。

但是,当我尝试通过任何两个或更多数据集的公用键连接时,我收到一条错误消息:似乎 d2 和 d3 公用的列会引发错误,即使其他键只为两个数据集公用数据集没问题。

我应该如何连接这三个数据集?

d1 <- data.frame(Y = "Y1", 
        N=1:3, 
        C= c(1, 3, 2),
        D= c(3, 1, 4),
        E= c(0, 1, 1),
        Q= c(2, 0, 3)) 

d2 <- data.frame(Y = "Y2", 
        N=1:3, 
        E= c(0, 1, 1),
        H= c(3, 1, 4),
        S= c(2, 2, 0)) 


d3 <- data.frame(Y = "Y3", 
        N=1:4, 
        C= c(4, 2, 1, 3),
        E= c(3, 1, 4, 2),
        H= c(1, 3, 2, 1), 
        U= c(3, 3, 1, 1))

join_all <- full_join(d1, d2, d3,
              by = c("Y", "N", "C", "E", "H"))

#Error: Join columns must be present in data.
#x Problem with `H`.

仅举个例子,这就是我想要的连接结果:

> desired_df <- data.frame(
+   Y= c("Y1", "Y1", "Y1", "Y2", "Y2", "Y2", "Y3", "Y3", "Y3", "Y3"), 
+   N= c(1, 2, 3, 1, 2, 3, 1, 2, 3, 4),
+   C= c(1, 3, 2, "NA", "NA", "NA", 4, 2, 1, 3), 
+   D= c(3, 1, 4, "NA", "NA", "NA", "NA", "NA", "NA", "NA"), 
+   E= c(0, 1, 1, 0, 1, 1, 3, 1, 4, 2),
+   H= c("NA","NA","NA", 3, 1, 4, 1, 3, 2, 1),
+   Q= c(2, 0, 3, "NA", "NA", "NA", "NA", "NA", "NA", "NA"), 
+   S= c("NA", "NA", "NA", 2, 2, 0, "NA", "NA", "NA", "NA"), 
+   U= c("NA", "NA", "NA", "NA", "NA", "NA", 3, 3, 1, 1))

> desired_df
    Y N  C  D E  H  Q  S  U
1  Y1 1  1  3 0 NA  2 NA NA
2  Y1 2  3  1 1 NA  0 NA NA
3  Y1 3  2  4 1 NA  3 NA NA
4  Y2 1 NA NA 0  3 NA  2 NA
5  Y2 2 NA NA 1  1 NA  2 NA
6  Y2 3 NA NA 1  4 NA  0 NA
7  Y3 1  4 NA 3  1 NA NA  3
8  Y3 2  2 NA 1  3 NA NA  3
9  Y3 3  1 NA 4  2 NA NA  1
10 Y3 4  3 NA 2  1 NA NA  1

最后:加入后,如何将NA变为0?

感谢您的帮助!

您可以将数据帧放入列表中,执行连接并将 NA 替换为 0。

library(tidyverse)
lst(d1, d2, d3) %>% reduce(full_join) %>% replace(is.na(.), 0)

#    Y N C D E Q H S U
#1  Y1 1 1 3 0 2 0 0 0
#2  Y1 2 3 1 1 0 0 0 0
#3  Y1 3 2 4 1 3 0 0 0
#4  Y2 1 0 0 0 0 3 2 0
#5  Y2 2 0 0 1 0 1 2 0
#6  Y2 3 0 0 1 0 4 0 0
#7  Y3 1 4 0 3 0 1 0 3
#8  Y3 2 2 0 1 0 3 0 3
#9  Y3 3 1 0 4 0 2 0 1
#10 Y3 4 3 0 2 0 1 0 1

在基础 R 中:

result <- Reduce(function(x, y) merge(x, y, all = TRUE), list(d1, d2, d3))
result[is.na(result)] <- 0
result

使用bind_rows

dplyr::bind_rows(d1, d2, d3)

输出:

    Y N  C  D E  Q  H  S  U
1  Y1 1  1  3 0  2 NA NA NA
2  Y1 2  3  1 1  0 NA NA NA
3  Y1 3  2  4 1  3 NA NA NA
4  Y2 1 NA NA 0 NA  3  2 NA
5  Y2 2 NA NA 1 NA  1  2 NA
6  Y2 3 NA NA 1 NA  4  0 NA
7  Y3 1  4 NA 3 NA  1 NA  3
8  Y3 2  2 NA 1 NA  3 NA  3
9  Y3 3  1 NA 4 NA  2 NA  1
10 Y3 4  3 NA 2 NA  1 NA  1

我们可以使用rbindlist

library(data.table)
rbindlist(list(d1, d2, d3), fill = TRUE)