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

R语言zoo::rollapply如何按index列数值而非行数设置滑动窗口

基于index数值范围的滑动窗口计算方案

前提说明

现有示例数据集结构如下:

dat = structure(list(index = c(10505L, 10506L, 10511L, 10539L, 10542L, 
10579L, 10642L, 11008L, 11012L, 13011L, 13110L, 13116L, 13118L, 
13156L, 13259L, 13273L, 13313L, 13365L, 13380L, 13382L, 13445L, 
13453L, 13482L, 13483L, 13494L, 13543L, 13550L, 14462L, 14464L, 
14564L, 14599L, 14604L, 14674L, 14719L, 14728L, 14775L, 14860L, 
14874L, 14930L, 14933L, 14975L, 15031L, 15089L, 15117L, 15179L, 
15211L, 15241L, 15245L, 15255L, 15260L, 15418L, 15585L, 15627L, 
15644L, 15774L, 15776L, 15777L, 15790L, 15791L, 15833L, 15849L, 
15850L, 15886L, 16042L, 16127L, 16140L, 16141L, 16142L, 16365L, 
16485L, 16489L, 16515L, 16542L, 16738L, 16834L, 16949L, 17272L, 
17462L, 17569L, 17571L, 17641L, 17654L, 17694L, 17695L, 17709L, 
17748L, 17836L, 17922L, 18643L, 20113L, 20131L, 28914L, 29318L, 
30524L, 30741L, 30912L, 30923L, 30998L, 46650L, 46698L), V2 = c(3L, 
3L, 3L, 2L, 2L, 2L, 2L, 1L, 0L, 3L, 2L, 2L, 2L, 0L, 1L, 1L, 0L, 
0L, 0L, 0L, 1L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 1L, 0L, 
0L, 0L, 1L, 2L, 2L, 2L, 2L, 1L, 0L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 
2L, 1L, 0L, 0L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 1L, 1L, 1L, 0L, 0L, 
0L, 0L, 0L, 2L, 3L, 5L, 3L, 0L, 0L, 3L, 1L, 0L, 3L, 0L, 0L, 2L, 
1L, 0L, 0L, 0L, 0L, 1L, 1L, 1L, 2L, 1L, 0L, 0L, 1L, 0L, 0L, 0L, 
1L, 1L, 1L)), row.names = c(NA, -100L), class = "data.frame")

需要计算的自定义函数如下:

n_sites = function(x) {
    return(sum(x > 1))
}

常规zoo::rollapply仅支持按行数设置窗口大小,使用方式如下:

zoo::rollapply(dat$V2, FUN=n_sites, width=100)

本次需求为不按行数定义窗口,而是基于index列的实际数值设置窗口范围,要求每个窗口覆盖约100个index数值单位。


可实现的解决方案

使用前请确保数据集已经按index列升序排序

方案1:基于data.table实现(推荐,性能更优,适配大数据量)

通过非等值连接匹配每个窗口内的所有行,再分组计算自定义函数:

library(data.table)
setDT(dat)
# 可根据需求调整窗口覆盖的index数值范围
window_size <- 100

# 计算每个左边界对应的窗口结果
res <- dat[, .(window_start = index, window_end = index + window_size)
           ][dat, on = .(window_start <= index, window_end >= index),
             .(n_sites_res = n_sites(V2)), by = .EACHI]

返回结果中每一行对应原数据每一行作为窗口左边界的计算结果,可按需调整窗口对齐规则(如右对齐只需修改window_end = index,window_start = index - window_size即可)。

方案2:基于zoo实现

将数据集转换为以index为索引的zoo对象,动态计算每个位置的窗口宽度后再滚动计算:

library(zoo)
# 构造以index为索引的zoo对象
z_dat <- zoo(dat$V2, order.by = dat$index)
window_size <- 100

# 计算每个位置对应的窗口行数
width_vec <- sapply(index(z_dat), function(x) {
  findInterval(x + window_size, index(z_dat)) - findInterval(x - 1e-9, index(z_dat))
})

# 左对齐滚动计算,可修改align参数调整对齐方式
res <- rollapply(z_dat, width = width_vec, FUN = n_sites, align = "left")

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.21 10:54:02