按 ID 合并两个不均匀的数据帧并填充缺失值
merge two uneven dataframes by ID and fill in missing values
我是 r 的新手。这是我的第一个论坛问题...我正在尝试合并两个这样的数据集:
df1 <- data.frame(ID = letters[1:5],
x = 5:9,
y = c(NA,6,5,NA,NA))
> df1
ID x y
1 a 5 NA
2 b 6 6
3 c 7 5
4 d 8 NA
5 e 9 NA
df2 <- data.frame(ID = letters[4:8],
y = 7:11,
z = c(4,3,NA,2,1))
> df2
ID y z
1 d 7 4
2 e 8 3
3 f 9 NA
4 g 10 2
5 h 11 1
结果应该是这样的:
> df3
ID x y z
1 a 5 NA NA
2 b 6 6 NA
3 c 7 5 NA
4 d 8 7 4
5 e 9 8 3
6 f NA 9 NA
7 g NA 10 2
8 h NA 11 1
我在各个论坛上四处寻找,但找不到解决这个特定问题的方法:/
非常感谢任何建议!
您可以先做一个 full_join
,然后使用 coalesce
将 NA
替换为 non-missing。
最后的 relocate
功能只是根据您想要的格式对列进行排序。
library(tidyverse)
full_join(df1, df2, by = "ID") %>%
mutate(y = coalesce(y.x, y.y), .keep = "unused") %>%
relocate(y, .after = x)
ID x y z
1 a 5 NA NA
2 b 6 6 NA
3 c 7 5 NA
4 d 8 7 4
5 e 9 8 3
6 f NA 9 NA
7 g NA 10 2
8 h NA 11 1
data.table
接近
library(data.table)
DT <- rbindlist(list(df1, df2), use.names = TRUE, fill = TRUE)
final <- DT[, lapply(.SD, max, na.rm = TRUE),keyby = ID]
# replace infinite values with NA
for (j in 1:ncol(final)) set(final, which(is.infinite(final[[j]])), j, NA)
# ID x y z
# 1: a 5 NA NA
# 2: b 6 6 NA
# 3: c 7 5 NA
# 4: d 8 7 4
# 5: e 9 8 3
# 6: f NA 9 NA
# 7: g NA 10 2
# 8: h NA 11 1
我们可以使用{powerjoin} :
library(powerjoin)
power_full_join(df1, df2, by = "ID", conflict = coalesce_xy)
#> ID x z y
#> 1 a 5 NA NA
#> 2 b 6 NA 6
#> 3 c 7 NA 5
#> 4 d 8 4 7
#> 5 e 9 3 8
#> 6 f NA NA 9
#> 7 g NA 2 10
#> 8 h NA 1 11
由 reprex package (v2.0.1)
于 2022-04-14 创建
使用 merge
+ aggregate
的基础 R 选项
aggregate(
. ~ ID,
merge(df1, df2, all = TRUE),
function(x) ifelse(all(is.na(x)), NA, na.omit(x)),
na.action = na.pass
)
给予
ID y x z
1 a NA 5 NA
2 b 6 6 NA
3 c 5 7 NA
4 d 7 8 4
5 e 8 9 3
6 f 9 NA NA
7 g 10 NA 2
8 h 11 NA 1
我是 r 的新手。这是我的第一个论坛问题...我正在尝试合并两个这样的数据集:
df1 <- data.frame(ID = letters[1:5],
x = 5:9,
y = c(NA,6,5,NA,NA))
> df1
ID x y
1 a 5 NA
2 b 6 6
3 c 7 5
4 d 8 NA
5 e 9 NA
df2 <- data.frame(ID = letters[4:8],
y = 7:11,
z = c(4,3,NA,2,1))
> df2
ID y z
1 d 7 4
2 e 8 3
3 f 9 NA
4 g 10 2
5 h 11 1
结果应该是这样的:
> df3
ID x y z
1 a 5 NA NA
2 b 6 6 NA
3 c 7 5 NA
4 d 8 7 4
5 e 9 8 3
6 f NA 9 NA
7 g NA 10 2
8 h NA 11 1
我在各个论坛上四处寻找,但找不到解决这个特定问题的方法:/
非常感谢任何建议!
您可以先做一个 full_join
,然后使用 coalesce
将 NA
替换为 non-missing。
最后的 relocate
功能只是根据您想要的格式对列进行排序。
library(tidyverse)
full_join(df1, df2, by = "ID") %>%
mutate(y = coalesce(y.x, y.y), .keep = "unused") %>%
relocate(y, .after = x)
ID x y z
1 a 5 NA NA
2 b 6 6 NA
3 c 7 5 NA
4 d 8 7 4
5 e 9 8 3
6 f NA 9 NA
7 g NA 10 2
8 h NA 11 1
data.table
接近
library(data.table)
DT <- rbindlist(list(df1, df2), use.names = TRUE, fill = TRUE)
final <- DT[, lapply(.SD, max, na.rm = TRUE),keyby = ID]
# replace infinite values with NA
for (j in 1:ncol(final)) set(final, which(is.infinite(final[[j]])), j, NA)
# ID x y z
# 1: a 5 NA NA
# 2: b 6 6 NA
# 3: c 7 5 NA
# 4: d 8 7 4
# 5: e 9 8 3
# 6: f NA 9 NA
# 7: g NA 10 2
# 8: h NA 11 1
我们可以使用{powerjoin} :
library(powerjoin)
power_full_join(df1, df2, by = "ID", conflict = coalesce_xy)
#> ID x z y
#> 1 a 5 NA NA
#> 2 b 6 NA 6
#> 3 c 7 NA 5
#> 4 d 8 4 7
#> 5 e 9 3 8
#> 6 f NA NA 9
#> 7 g NA 2 10
#> 8 h NA 1 11
由 reprex package (v2.0.1)
于 2022-04-14 创建使用 merge
+ aggregate
aggregate(
. ~ ID,
merge(df1, df2, all = TRUE),
function(x) ifelse(all(is.na(x)), NA, na.omit(x)),
na.action = na.pass
)
给予
ID y x z
1 a NA 5 NA
2 b 6 6 NA
3 c 5 7 NA
4 d 7 8 4
5 e 8 9 3
6 f 9 NA NA
7 g 10 NA 2
8 h 11 NA 1