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

基于组内历史值生成新计数变量的dplyr实现问询

用dplyr实现分组计算距离上次X1=1的周期数

我来帮你搞定这个需求!你需要在每个分组内,计算当前行距离上一次X1取值为1的周期数,并且在之前没有出现过1的行填充NA。下面是用dplyr(结合tidyr的fill函数)实现的完整方案:

示例数据

首先先确认我们的输入数据:

data_test <- data.frame(
 group = rep(1:4, each = 5),
 time = rep(1:5, n = 4),
 X1 = c(0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1)
)

解决方案代码

library(dplyr)
library(tidyr)

data_test <- data_test %>%
  group_by(group) %>%
  mutate(
    # 标记X1=1所在的行号,其他行设为NA
    last_one_pos = ifelse(X1 == 1, row_number(), NA),
    # 向前填充最近的X1=1的行号,这样每一行都能拿到最近的1的位置
    last_one_pos = fill(last_one_pos, .direction = "down"),
    # 计算当前行到最近的1的周期数:行号差减1
    X2 = row_number() - last_one_pos - 1,
    # 处理NA的情况:
    # 1. 第一个1出现之前的行(last_one_pos仍为NA)
    # 2. 第一个1所在的行(当前行号等于last_one_pos)
    X2 = case_when(
      is.na(last_one_pos) ~ NA_integer_,
      row_number() == last_one_pos ~ NA_integer_,
      TRUE ~ X2
    )
  ) %>%
  ungroup()

代码解释

我们一步步拆解逻辑:

  • 分组:用group_by(group)确保所有计算都在每个分组内独立进行。
  • 标记1的位置:last_one_pos变量记录每个X1=1的行号,其他行暂时为NA。
  • 填充最近的1的位置:fill(last_one_pos, .direction = "down")会把每个NA替换成上方最近的非NA值,这样每一行都能知道离它最近的上一个1在哪里。
  • 计算周期数:用当前行号减去最近的1的行号,再减1,就得到了中间间隔的周期数(比如当前行是第4行,最近的1在第3行,4-3-1=0,和示例一致)。
  • 修正NA值:通过case_when把两种需要设为NA的情况筛选出来:还没出现过1的行,以及第一个1所在的行。

运行这段代码后,生成的X2就和你提供的示例完全匹配啦!

内容的提问来源于stack exchange,提问作者Tim Welsh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 08:12:51