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

使用dplyr实现数值由正转负时生成新分组ID的问题

问题解答

1. 为何cumsum()结合ifelse()会全生成NA?

核心原因是dplyr::lag(X, n=1)的第一个返回值是NA。当执行ifelse(X < 0 & lag(X) > 0, 1, 0)时,第一行的条件判断结果为NA——逻辑运算中只要有NA参与,结果必然是NA。而cumsum()的特性是:一旦累加序列中出现NA,后续所有累加结果都会被污染成NA,最终导致tile_x列全为NA。

单独运行ifelse()时,只有第一行是NA,其余行能正常返回0或1;但传入cumsum()后,NA会直接扩散到所有结果。

2. 不依赖ifelse()/cumsum()的简洁实现

根据你标记转折点后所有行为1、之前为0的需求,提供以下几种简洁方案:

方法一:直接定位转折点赋值(无ifelse/cumsum)

先找到“前值>0、当前值<0”的转折点行号,再通过行号判断赋值:

df1 <- df %>%
  mutate(
    tile_x = as.integer(row_number() >= which(X < 0 & lag(X) > 0))
  )

如果存在多个转折点,该方法会自动标记第一个转折点后的所有行为1,适配你“分组长度可变但模式一致”的要求。

方法二:用replace函数赋值(无ifelse/cumsum)

通过replace直接替换指定行的值,逻辑更直观:

turn_idx <- which(df$X < 0 & lag(df$X) > 0)

df1 <- df %>%
  mutate(tile_x = replace(rep(0, n()), row_number() >= turn_idx, 1))

方法三:分组标识法(仅用cumsum,无ifelse)

若允许使用cumsum,可通过标记分组起始点生成连续分组编号:

df1 <- df %>%
  mutate(
    # 标记分组起始:第一行 + 转折点行
    group_start = c(TRUE, X[-1] < 0 & X[-n()] > 0),
    tile_x = cumsum(group_start) - 1
  ) %>%
  select(-group_start)

该方案支持多个转折点生成0、1、2...的连续分组编号,扩展性更强。


内容的提问来源于stack exchange,提问作者L Tyrone

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 14:15:13