R中如何合并带年份范围与单年份的两个dataframe并匹配unique_id
R 实现同名不同出生日期的数据框匹配方案
核心逻辑
- 先给
data1增加唯一行标识,避免重名记录混淆 - 按
name字段关联两个数据框,拿到同一个姓名下所有可能的匹配项 - 对每个
data1的记录,优先选择year_of_birth落在[min_year, max_year]区间的匹配项,无符合项则选和区间距离最小的项 - 每个
data1记录只保留最优的1条匹配结果
实现代码
首先加载依赖包(tidyverse是R数据处理常用工具集,新手直接安装加载即可):
# 安装包(首次运行执行,后续可以注释掉) # install.packages("tidyverse") library(tidyverse) # 你的原始数据 data1<-data.frame(name=c("Jessica_Smith","John_Smith","John_Smith") , max_year=c(2000,1989,2005), min_year=c(1990,1989,2001)) data2<-data.frame(name=c("Jessica_Smith","John_Smith","John_Smith") , year_of_birth=c(1995,1989,2002),unique_id=c("aby37","nf93","fnd34")) # 匹配处理 result <- data1 %>% # 给data1加行号,保证每条原始记录都能对应 mutate(row_id = row_number()) %>% # 按姓名关联所有可能的data2记录 left_join(data2, by = "name") %>% # 按data1的每条记录分组 group_by(row_id) %>% # 计算和区间的最小距离:在区间内距离为0,小于区间取到min的差,大于取到max的差 mutate( year_diff = case_when( year_of_birth >= min_year & year_of_birth <= max_year ~ 0, year_of_birth < min_year ~ min_year - year_of_birth, TRUE ~ year_of_birth - max_year ) ) %>% # 按距离升序排列,距离越小优先级越高 arrange(year_diff) %>% # 取第一条最优匹配 slice(1) %>% # 去掉不需要的辅助列 ungroup() %>% select(-row_id, -year_diff)
输出结果示例
运行后得到的result就是匹配完成的表,自带对应unique_id,结果如下:
| name | max_year | min_year | year_of_birth | unique_id |
|---|---|---|---|---|
| Jessica_Smith | 2000 | 1990 | 1995 | aby37 |
| John_Smith | 1989 | 1989 | 1989 | nf93 |
| John_Smith | 2005 | 2001 | 2002 | fnd34 |
如果你处理的数据量超过10万行,可以改用
data.table包的滚动连接实现,运算速度会快很多,基础逻辑和上述方案一致。
内容的提问来源于stack exchange,提问作者sd3184
相关产品推荐
相关产品推荐

