You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

R语言:合并行数不同的DataFrame,按ID匹配无重复行且缺省填0

解决R语言DataFrame按id合并并填充缺失值的问题

问题分析

直接用merge()仅按id合并时,同一id在两个表中存在多行的情况下会生成笛卡尔积,导致行重复。正确的思路是给每个id下的行添加组内序号,通过id+组内序号的组合实现行的一一匹配,再把无匹配的salary值替换为0。

方法一:Base R实现

# 定义原始数据框
df <- data.frame("id" = c(1,1,1,2,2,3,3,4,4,5,5,5),"occ"=c(1,1,2,2,2,1,1,2,2,1,2,2))
df1 <- data.frame("id" = c(1,1,2,2,3,3,4,4,5,5),"salary"= c(10,11,12,13,14,15,16,17,18,19))

# 为每个id添加组内行号
df$rn <- ave(df$id, df$id, FUN = seq_along)
df1$rn <- ave(df1$id, df1$id, FUN = seq_along)

# 按id和组内行号左连接,保留df的所有行
merged <- merge(df, df1, by = c("id", "rn"), all.x = TRUE)

# 将salary列的NA替换为0
merged$salary[is.na(merged$salary)] <- 0

# 移除辅助列rn,得到目标结果
merged <- merged[, c("id", "occ", "salary")]

# 查看结果
print(merged)

方法二:dplyr包实现(更简洁)

library(dplyr)

# 定义原始数据框
df <- data.frame("id" = c(1,1,1,2,2,3,3,4,4,5,5,5),"occ"=c(1,1,2,2,2,1,1,2,2,1,2,2))
df1 <- data.frame("id" = c(1,1,2,2,3,3,4,4,5,5),"salary"= c(10,11,12,13,14,15,16,17,18,19))

merged <- df %>%
  group_by(id) %>%
  mutate(rn = row_number()) %>%  # 给每个id下的行加序号
  left_join(
    df1 %>% group_by(id) %>% mutate(rn = row_number()),
    by = c("id", "rn")
  ) %>%
  mutate(salary = replace_na(salary, 0)) %>%  # 将NA替换为0
  ungroup() %>%
  select(id, occ, salary)  # 选择需要的列

# 查看结果
print(merged)

两种方法最终输出都会符合期望格式:同一id下的行按顺序匹配,无对应匹配的行salary自动填充为0。

内容的提问来源于stack exchange,提问作者mehmo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 07:14:55