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

R中替代嵌套for循环实现分组连续FALSE计数的方案

R中高效实现分组数据集的连续FALSE统计转换

示例原始数据

先构造一份符合需求的示例数据,方便验证转换逻辑:

library(dplyr)
library(purrr)

df <- tibble(
  group = rep(c("A", "B"), each = 5),
  id = 1:10,
  flag = c(FALSE, FALSE, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE)
)

核心转换代码

这里用dplyr做分组,purrr::reduce实现无嵌套循环的高效计算,完全符合规则要求:

df_transformed <- df %>%
  group_by(group) %>%
  mutate(
    new_col = reduce(
      rev(tail(flag, -1)), 
      ~ if (.y) 0 else .x + 1, 
      .init = 0
    ) %>% rev() %>% c(., 0)
  ) %>%
  ungroup()

逻辑解释

  • 分组处理:group_by(group)确保每个分组独立计算,互不干扰
  • 取后续行序列:tail(flag, -1)提取每个分组中当前行的下一行到最后一行的flag值
  • 反向累计计算:
    • 反转序列后用reduce从后往前遍历:如果当前flag是TRUE,直接重置为0;如果是FALSE,就在前一个结果基础上加1(统计连续数量)
    • .init=0对应分组最后一行的new_col固定为0
  • 恢复顺序并补全:反转累计结果回到原行顺序,最后补0作为分组最后一行的数值

转换结果

运行代码后得到的目标数据集:

print(df_transformed)
#> # A tibble: 10 × 4
#>    group    id flag  new_col
#>    <chr> <int> <lgl>   <dbl>
#>  1 A         1 FALSE       1
#>  2 A         2 FALSE       0
#>  3 A         3 TRUE        2
#>  4 A         4 FALSE       1
#>  5 A         5 FALSE       0
#>  6 B         6 TRUE        3
#>  7 B         7 FALSE       2
#>  8 B         8 FALSE       1
#>  9 B         9 FALSE       0
#> 10 B        10 TRUE        0

可以看到完全符合规则:

  • 分组首行根据下一行开始的连续FALSE数填充(如A组首行下一行是FALSE,连续1个后遇TRUE,填1)
  • 下一行是TRUE的行直接填0(如A组第二行)
  • 每个分组最后一行固定填0

大数据场景优化(data.table版本)

如果你的数据集很大,用data.table会更高效:

library(data.table)
setDT(df)

df_transformed <- df[, {
  tail_flag <- tail(flag, -1)
  new_col_part <- reduce(rev(tail_flag), ~if(.y) 0 else .x+1, .init=0) %>% rev()
  new_col <- c(new_col_part, 0)
  .(id, flag, new_col)
}, by = group]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 02:55:22