如何用R语言dplyr创建二元变量判断个体上年是否被观测
问题解决思路及代码
你的代码之所以生成全0的obs列,核心问题有两个:
- 多余的
rowwise():开启行式计算后,group_by(id)的分组逻辑失效,lag(year)没法正确取到同个id下的上一行年份值。 - 条件判断冗余且错误:分组后
lag(year)本来就是当前id组内的上一年份,没必要再去原数据框里匹配同id的年份列表,这会导致逻辑判断出错。
正确实现代码
根据你“标记个体是否在上一年被观测到”的需求,这里提供两种靠谱的实现方式:
方式一:适用于年份连续的场景
如果你的数据里每个id的观测年份是连续的(比如没有隔年缺失),可以直接通过年份差判断:
library(dplyr) df2 <- df %>% arrange(id, year) %>% group_by(id) %>% # 判断当前年份是否等于上一个观测年份+1,是则标记1,否则0 mutate(obs = ifelse(year == lag(year) + 1, 1, 0)) %>% # 每组第一行没有上一年数据,把NA替换为0 replace_na(list(obs = 0)) %>% ungroup()
方式二:适用于年份可能不连续的场景
如果存在某id隔年缺失数据的情况(比如有2020、2022年数据,2021年没记录),这种方式能准确判断前一年是否有观测:
library(dplyr) df2 <- df %>% arrange(id, year) %>% group_by(id) %>% # 检查当前年份的前一年是否在该id的观测年份列表里,是则转1,否则0 mutate(obs = as.integer((year - 1) %in% year)) %>% ungroup()
符合预期的输出示例
处理后的数据会呈现如下逻辑(匹配你期望的标记规则):
| id | year | fte_wage | obs |
|---|---|---|---|
| 1 | 1 | 45 | 0 |
| 1 | 2 | 134 | 1 |
| 1 | 3 | 23 | 1 |
| 2 | 2 | 134 | 0 |
| 2 | 3 | 23 | 1 |
| 3 | 3 | 34 | 0 |
内容的提问来源于stack exchange,提问作者Lucas
相关产品推荐
相关产品推荐

