如何通过full_join合并df.old与df.new并填充缺失值、整合新列新行
问题描述
我有两个数据框df.old和df.new:
df.old包含分组变量grp,其中分组2的A_t1、B_t1、C_t1存在缺失值,这些缺失值可在df.new中找到对应数据- 需要以
PID为键对两个数据框执行全连接,用df.new的数据填充缺失值,同时保留df.new的额外列(A_t2)和新增行(PID21-23) - 最终输出需包含PID1至23,列
A_t1、B_t1、C_t1、A_t2,且A_t1、B_t1、C_t1无缺失值
生成数据的代码
size.old <- 20 set.seed(1) # 生成df.old:分组2的A_t1、B_t1、C_t1为缺失值 df.old <- data.frame(PID = 1:size.old, grp = sample(1:3, size.old, replace = TRUE), A_t1 = sample(1:10, size.old, replace = TRUE), B_t1 = sample(1:10, size.old, replace = TRUE), C_t1 = sample(1:10, size.old, replace = TRUE) ) %>% mutate(A_t1 = ifelse(grp == 2, NA, A_t1), B_t1 = ifelse(grp == 2, NA, A_t1), C_t1 = ifelse(grp == 2, NA, A_t1)) %>% arrange(grp) # df.old输出预览 # PID grp A_t1 B_t1 C_t1 # 1 1 1 5 5 5 # 2 3 1 9 9 9 # 3 5 1 5 5 5 # 4 12 1 3 3 3 # 5 13 1 6 6 6 # 6 14 1 10 10 10 # 7 20 1 9 9 9 # 8 4 2 NA NA NA # 9 8 2 NA NA NA # 10 9 2 NA NA NA # 11 15 2 NA NA NA # 12 16 2 NA NA NA # 13 17 2 NA NA NA # 14 18 2 NA NA NA # 15 2 3 5 5 5 # 16 6 3 5 5 5 # 17 7 3 2 2 2 # 18 10 3 1 1 1 # 19 11 3 4 4 4 # 20 19 3 10 10 10 # 生成df.new:包含分组2缺失值的补充数据,以及新增PID21-23的行 df.new <- data.frame(PID = c(4, 8, 9, 15, 16, 17, 18, 20, 21, 22, 23), A_t1 = sample(1:10, size=11, replace = TRUE), A_t2 = sample(1:10, size=11, replace = TRUE) ) # df.new输出预览 # PID A_t1 A_t2 # 1 4 2 10 # 2 8 2 8 # 3 9 3 10 # 4 15 1 4 # 5 16 2 5 # 6 17 3 9 # 7 18 3 5 # 8 20 3 7 # 9 21 8 5 # 10 22 9 6 # 11 23 2 4
原尝试代码的问题
直接执行全连接只会将重复列重命名(如A_t1.x、A_t1.y),不会自动填充缺失值:
# 此代码仅重命名公共列而非填充缺失值 full_join(df.old, df.new, by = "PID")
解决方案
使用dplyr的full_join结合coalesce函数填充缺失值,同时根据df.old的规律(非缺失行的B_t1、C_t1与A_t1值一致)处理对应列的缺失:
library(dplyr) df_final <- full_join(df.old, df.new, by = "PID") %>% # 用df.new的A_t1填充df.old的A_t1缺失值 mutate(A_t1 = coalesce(A_t1.x, A_t1.y), # 处理B_t1:原缺失值用填充后的A_t1赋值,否则保留原值 B_t1 = ifelse(is.na(B_t1), A_t1, B_t1), # 处理C_t1:逻辑同B_t1 C_t1 = ifelse(is.na(C_t1), A_t1, C_t1), # 保留A_t2列,无数据的行设为NA(若需要填充可自行补充规则) A_t2 = A_t2) %>% # 选择需要的列并按PID排序 select(PID, grp, A_t1, B_t1, C_t1, A_t2) %>% arrange(PID) # 查看结果示例 head(df_final, 10)
结果说明
- 分组2的
A_t1、B_t1、C_t1已用df.new的数据填充,无缺失值 - 新增的PID21-23行完整保留,包含
A_t1和A_t2数据 - 原
df.old中无A_t2的行(如PID1、3等),A_t2列显示为NA,若需要填充可根据业务规则添加逻辑(比如设为0或其他默认值)
内容的提问来源于stack exchange,提问作者D. Studer
相关产品推荐
相关产品推荐

