R语言left_join():替换匹配行值而非新增列的实现方法
用B数据框匹配更新A数据框的实现方案
现有数据框
数据框A
A <- data.frame(AgentNo=c(1,2,3,4,5,6), N=c(2,5,6,1,9,0), Rarity=c(1,2,1,1,2,2))
输出:
AgentNo N Rarity 1 1 2 1 2 2 5 2 3 3 6 1 4 4 1 1 5 5 9 2 6 6 0 2
数据框B
B <- data.frame(Rank=c(1,5), AgentNo.x=c(2,5), AgentNo.y=c(1,4), N=c(3,1), Rarity=c(1,2))
输出:
Rank AgentNo.x AgentNo.y N Rarity 1 1 2 1 3 1 2 5 5 4 1 2
需求说明
- 按
A.AgentNo = B.AgentNo.y且A.N = B.N的条件,将B左连接到A - 不新增列,仅用B中的值更新A的匹配行:
- 匹配行的
A.AgentNo替换为B.AgentNo.x A.N替换为B.NA.Rarity替换为B.Rarity
- 匹配行的
- 丢弃B中的
Rank和AgentNo.y列
期望结果
Result <- data.frame(AgentNo=c(2,2,3,5,5,6), N=c(3,5,6,1,9,0), Rarity=c(1,2,1,2,2,2))
输出:
AgentNo N Rarity 1 2 3 1 2 2 5 2 3 3 6 1 4 5 1 2 5 5 9 2 6 6 0 2
实现方案
方法1:使用dplyr包
library(dplyr) # 清洗B数据,保留需要的列并重新命名匹配键 B_clean <- B %>% select(AgentNo.y, AgentNo.x, N, Rarity) %>% rename(AgentNo_match = AgentNo.y, N_match = N, new_AgentNo = AgentNo.x, new_N = N, new_Rarity = Rarity) # 左连接后替换匹配行的值,非匹配行保留原数据 Result <- A %>% left_join(B_clean, by = c("AgentNo" = "AgentNo_match", "N" = "N_match")) %>% mutate( AgentNo = ifelse(!is.na(new_AgentNo), new_AgentNo, AgentNo), N = ifelse(!is.na(new_N), new_N, N), Rarity = ifelse(!is.na(new_Rarity), new_Rarity, Rarity) ) %>% select(-starts_with("new_")) # 移除临时新增的辅助列
方法2:基础R实现
# 生成匹配键字符串,找到A中与B匹配的行索引 match_idx <- match(paste(A$AgentNo, A$N), paste(B$AgentNo.y, B$N)) # 复制原数据框作为结果模板 Result <- A # 替换匹配行的对应字段 Result$AgentNo[!is.na(match_idx)] <- B$AgentNo.x[match_idx[!is.na(match_idx)]] Result$N[!is.na(match_idx)] <- B$N[match_idx[!is.na(match_idx)]] Result$Rarity[!is.na(match_idx)] <- B$Rarity[match_idx[!is.na(match_idx)]]
内容的提问来源于stack exchange,提问作者locket
相关产品推荐
相关产品推荐

