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

如何在分组滑动窗口中按条件统计hr>0的出现次数?

分组滑动窗口统计hr>0的次数

示例数据集

structure(list(id = c("AA2A", "AA2A", "AA2A", "AA2A", "AA2A", 
"AA2A", "XX7H", "XX7H", "XX7H", "XX7H", "XX7H", "XX7H"), hr = c(31L, 
31L, 31L, 0L, 0L, 50L, 50L, 0L, 0L, 0L, 0L, 84L)), class = "data.frame", row.names = c(NA, 
-12L))

需求

针对每个id,在大小为3的滑动窗口中统计hr>0的出现次数,生成新列result。

尝试过的无效代码

slider包

mutate(result = slide_dbl(hr,length(hr>0), .before = 3, .after = 0, .complete = FALSE))
mutate(result = slide_dbl(hr,summarise_if(hr>0), .before = 3, .after = 0, .complete = FALSE))

zoo包

mutate(result=rollapply(hr, width=3, FUN=function(x) length(hr>0), partial=TRUE, align='left'))

注:完整数据集含100万行、10列,zoo包代码运行过慢;此前用slide_dbl计算均值、中位数正常,但添加hr>0条件后失效;分组操作group_by(id)无问题,工作环境为tidyverse。


解决方案

正确的slider包实现

核心问题是你在slide_dbl里传入的函数错误:应该针对**窗口内的子集x**计算,而不是引用整个列hr。同时要注意窗口参数的设置,确保窗口大小为3:

library(tidyverse)
library(slider)

df %>%
  group_by(id) %>%
  mutate(
    # 窗口为当前行 + 前2行,共3行;不足3行时仍计算(.complete=FALSE)
    result = slide_dbl(hr, ~sum(.x > 0), .before = 2, .complete = FALSE)
    # 如果需要窗口是当前行 + 后2行(对应zoo的align='left'),则用:
    # result = slide_dbl(hr, ~sum(.x > 0), .after = 2, .complete = FALSE)
  ) %>%
  ungroup()

代码解释

  • ~sum(.x > 0):匿名函数,对每个滑动窗口内的hr值,统计大于0的数量(sum(逻辑值)等价于计数TRUE的个数,比length(which(.x>0))更高效)。
  • .before = 2:表示窗口包含当前行及前面2行,总大小为3;如果你的需求是从当前行往后取3个(和zoo的align='left'一致),则改用.after = 2。
  • slider包基于C++实现,性能远优于zoo的rollapply,适合百万级行的大数据集。

针对示例数据集的输出

运行上述代码后,示例数据的结果如下(以.before=2为例):

# A tibble: 12 × 3
   id      hr result
   <chr> <int>  <int>
 1 AA2A    31      1
 2 AA2A    31      2
 3 AA2A    31      3
 4 AA2A     0      2
 5 AA2A     0      1
 6 AA2A    50      1
 7 XX7H    50      1
 8 XX7H     0      2
 9 XX7H     0      1
10 XX7H     0      0
11 XX7H     0      0
12 XX7H    84      1

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 03:43:29