键变量在左右数据框中均含多行时的数据集匹配:为工作信息Dataframe添加求学城市匹配指示列
为工作记录DataFrame添加求学城市匹配标识列
我来帮你搞定这个需求!你需要给记录工作情况的DataFrame(也就是mydf1)加一列,用来标记当前行的工作城市是不是这个个体曾经读过书的城市,对吧?下面给你清晰的实现思路和两种可行的代码方案:
核心思路
先为每个个体整理出所有曾求学的城市集合,再把这个集合和工作记录关联,判断每行的work_city是否属于对应个体的求学城市集合,最后生成0/1的标识列。
方案一:使用dplyr包(简洁高效)
步骤1:构造示例数据
先把你给出的示例数据定义好:
mydf1 <- data.frame(id=c('A','A','A','A','B','B','B','C'), period=c(1,1,2,2,1,1,2,1), work_city=c('x','y','x','y','w','k','w','k')) mydf2 <- data.frame(id=c('A','A','B','B','C','C'), study_city=c('x','w','x','k','y','k'))
步骤2:聚合个体的求学城市
用dplyr的分组聚合功能,为每个id生成包含所有求学城市的列表:
library(dplyr) # 需要先加载dplyr包 # 为每个id聚合唯一的求学城市 study_city_map <- mydf2 %>% group_by(id) %>% summarise(study_cities = list(unique(study_city)))
步骤3:合并数据并生成标识列
将聚合后的求学城市映射和mydf1合并,然后判断每行的工作城市是否在对应个体的求学城市列表中:
mydf_final <- mydf1 %>% left_join(study_city_map, by = "id") %>% # 判断工作城市是否在求学城市列表中,生成0/1标识 mutate(same_city = as.integer(work_city %in% unlist(study_cities)), # 转换成字符型,和你期望的输出格式一致 same_city = as.character(same_city)) %>% # 移除中间辅助列 select(-study_cities)
方案二:基础R实现(无需额外包)
如果你不想加载dplyr包,用基础R也能实现:
# 构造示例数据(和上面一致) mydf1 <- data.frame(id=c('A','A','A','A','B','B','B','C'), period=c(1,1,2,2,1,1,2,1), work_city=c('x','y','x','y','w','k','w','k')) mydf2 <- data.frame(id=c('A','A','B','B','C','C'), study_city=c('x','w','x','k','y','k')) # 生成每个id对应的求学城市列表 study_city_list <- tapply(mydf2$study_city, mydf2$id, unique) # 为mydf1添加same_city列 mydf_final <- mydf1 mydf_final$same_city <- as.character(mapply(function(id, city) { # 判断当前城市是否在该个体的求学城市列表中,返回0或1 as.integer(city %in% study_city_list[[id]]) }, mydf_final$id, mydf_final$work_city))
验证结果
不管用哪种方案,最终得到的mydf_final都和你期望的完全一致:
> mydf_final id period work_city same_city 1 A 1 x 1 2 A 1 y 0 3 A 2 x 1 4 A 2 y 0 5 B 1 w 0 6 B 1 k 1 7 B 2 w 0 8 C 1 k 1
内容的提问来源于stack exchange,提问作者PaulaSpinola
相关产品推荐
相关产品推荐

