如何结合mutate、if语句与group_by为数据框添加参考人职业列?
为家庭数据添加参考人职业列的解决方案
原始数据与需求
数据构造代码
c <- data.frame(HH_ID=c(1,2,3,1,2,3), WORK = c("Worker", "Manager", "Employee", "Employee", "Manager", "Craftsman"), NOI= c(1,1,1,2,2,2))
需求描述
新增一列Reference_Work,填入每个家庭中参考人(NOI=1)的职业,期望输出如下:
HH_ID WORK NOI Reference_Work 1 Worker 1 Worker 2 Manager 1 Manager 3 Employee 1 Employee 1 Employee 2 Worker 2 Manager 2 Manager 3 Craftsman 2 Employee
尝试的错误代码
df <- c %>% group_by(HH_ID) %>% mutate(NewVar = if(c$NOI == 2) {coalesce(lag(WORK), lead(WORK))} else {WORK})
错误分析
- 在
dplyr分组管道中使用c$NOI会引用整个原始数据框的列,而非当前分组内的列,逻辑错误; - 依赖
lag/lead获取参考人职业的方式不可靠,若参考人不是分组内的首行/末行,结果会出错。
正确解法
解法1:分组直接提取参考人职业
利用分组操作,直接提取每组中NOI=1对应的职业值,代码简洁直接:
library(dplyr) df <- c %>% group_by(HH_ID) %>% mutate(Reference_Work = WORK[NOI == 1]) %>% ungroup()
解法2:构建映射表后关联
先提取每个家庭的参考人职业,再通过家庭ID关联回原数据,不依赖行顺序,更稳健:
library(dplyr) # 生成参考人职业映射表 ref_work_map <- c %>% filter(NOI == 1) %>% select(HH_ID, Reference_Work = WORK) # 关联到原数据 df <- c %>% left_join(ref_work_map, by = "HH_ID")
内容的提问来源于stack exchange,提问作者Victor LE FRANC
相关产品推荐
相关产品推荐

