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