r-如何在dplyr中完全连接多个数据集(ncol不匹配)



我有三个数据帧(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)

最新更新