You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

复杂条件变异:如何仅基于参与者过往观测值创建新变量?

基于参与者过往观测创建新变量的解决方案

针对你提供的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 11:55:33