复杂条件变异:如何仅基于参与者过往观测值创建新变量?
基于参与者过往观测创建新变量的解决方案
针对你提供的fbwb数据框,我们可以用R的dplyr包(以及可选的slider包)轻松实现基于参与者过往观测的复杂变异操作。下面我会给出几种常见需求的实现代码和解释。
先重现你的数据
首先确保我们的数据集一致:
fbwb <- read.table(text="id year bully1 bully2 bully3 cbully bully_ever 100 1 NA 1 NA 1 1 100 2 1 1 NA 1 1 100 3 NA 0 NA 0 1 101 1 NA NA 1 1 1 102 1 NA 1 NA 1 1 102 2 NA NA NA NA 1 102 3 NA 1 1 1 1 102 4 0 0 0 0 1 103 1 NA 1 NA 1 1 103 2 NA 0 0 0 1", header=TRUE)
基础需求:判断过往是否有过欺凌、计算过往欺凌总次数
我们先创建两个实用的新变量:
past_any_bully:当前年份之前,该参与者是否有过任何一次欺凌行为(bully1/bully2/bully3中至少一个为1)past_bully_total:当前年份之前,该参与者所有欺凌行为的总次数
实现代码:
# 安装并加载dplyr(如果未安装) # install.packages("dplyr") library(dplyr) fbwb_processed <- fbwb %>% # 按参与者分组,确保同一参与者的观测按年份排序 group_by(id) %>% arrange(year, .by_group = TRUE) %>% mutate( # 先标记当前行是否存在欺凌行为(忽略NA,只要有一个1就算) current_row_bully = ifelse(rowSums(select(., bully1:bully3) == 1, na.rm = TRUE) > 0, 1, 0), # 过往是否有过欺凌:用累积最大值判断,lag移位排除当前行 past_any_bully = lag(cummax(current_row_bully), default = 0), # 过往欺凌总次数:累积求和后移位排除当前行 past_bully_total = lag(cumsum(current_row_bully), default = 0) ) %>% # 移除中间辅助变量(可选) select(-current_row_bully) %>% ungroup() # 查看结果 print(fbwb_processed)
输出结果示例:
# A tibble: 10 × 8 id year bully1 bully2 bully3 cbully bully_ever past_any_bully past_bully_total <int> <int> <int> <int> <int> <int> <int> <dbl> <dbl> 1 100 1 NA 1 NA 1 1 0 0 2 100 2 1 1 NA 1 1 1 1 3 100 3 NA 0 NA 0 1 1 2 4 101 1 NA NA 1 1 1 0 0 5 102 1 NA 1 NA 1 1 0 0 6 102 2 NA NA NA NA 1 1 1 7 102 3 NA 1 1 1 1 1 1 8 102 4 0 0 0 0 1 1 3 9 103 1 NA 1 NA 1 1 0 0 10 103 2 NA 0 0 0 1 1 1
扩展需求:按测量方式分别判断过往是否出现欺凌
如果你需要针对bully1、bully2、bully3分别统计过往是否出现过1,可以用下面的代码:
fbwb_processed <- fbwb %>% group_by(id) %>% arrange(year, .by_group = TRUE) %>% mutate( # 处理NA:将NA转为0,避免影响累积最大值计算 past_bully1 = lag(cummax(ifelse(is.na(bully1), 0, bully1)), default = 0), past_bully2 = lag(cummax(ifelse(is.na(bully2), 0, bully2)), default = 0), past_bully3 = lag(cummax(ifelse(is.na(bully3), 0, bully3)), default = 0) ) %>% ungroup()
进阶需求:判断过往连续N年是否有欺凌
如果需要更复杂的条件(比如判断过往2年是否连续出现欺凌),可以用slider包实现滑动窗口计算:
# 安装并加载slider(如果未安装) # install.packages("slider") library(slider) fbwb_processed <- fbwb %>% group_by(id) %>% arrange(year, .by_group = TRUE) %>% mutate( current_row_bully = ifelse(rowSums(select(., bully1:bully3) == 1, na.rm = TRUE) > 0, 1, 0), # 检查过往2年是否连续有欺凌(不包含当前年份) past_2y_consec_bully = lag(slide_dbl(current_row_bully, ~all(.x == 1), .before = 1, .after = -1), default = 0) ) %>% ungroup()
这里的slide_dbl函数会创建一个滑动窗口,.before=1表示取当前行的前1行(即上一年),.after=-1表示排除当前行,all(.x ==1)判断窗口内的所有值是否都是1,最后用lag()确保结果对应“过往”的观测。
内容的提问来源于stack exchange,提问作者dam4l10
相关产品推荐
相关产品推荐

