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

如何用zoo/slider计算points相对values滚动4窗口的百分位秩?

滚动窗口百分位秩计算方案

需求:为给定数据框新增percentile_rank列,每行的取值逻辑是:计算该行points值在values列**当前行及前3行(共4个值)**滚动窗口中的百分位秩。

给定数据:

df <- data.frame(
  type = rep(c("A","B"),times = 10),
  values = c(16,16,16,16,16,17,18,18,20,20,45,44,45,44,45,47,45,46,47,50),
  points = c(20,14,34,44,40,50,44,34,43,23,60,61,62,63,64,65,66,67,68,69)
)

方法1:使用slider包

slider的slide_dbl函数支持灵活定义滚动窗口范围,直接对数据框的子窗口操作:

library(slider)

df$percentile_rank <- slide_dbl(
  .x = df,
  .f = function(window) {
    window_values <- window$values
    current_point <- window$points[nrow(window)]
    # 计算0-100范围的百分位秩
    ecdf(window_values)(current_point) * 100
  },
  .before = 3,  # 包含当前行前3行
  .after = 0,   # 不包含当前行之后的行
  .complete = FALSE  # 允许窗口不足4行(前3行按实际行数计算)
)

方法2:使用zoo包

zoo::rollapply通过矩阵组合values和points,指定右对齐窗口实现需求:

library(zoo)

# 组合values和points为矩阵,方便窗口内同时获取两个列的数据
data_matrix <- cbind(df$values, df$points)

df$percentile_rank_zoo <- rollapply(
  data_matrix,
  width = 4,
  FUN = function(window_mat) {
    window_values <- window_mat[, 1]
    current_point <- window_mat[nrow(window_mat), 2]
    ecdf(window_values)(current_point) * 100
  },
  align = "right",  # 窗口右对齐,确保当前行是窗口最后一个元素
  partial = TRUE    # 允许窗口不足4行时计算,保留前3行的结果
)

说明

  • 百分位秩通过经验累积分布函数ecdf计算,返回0-100的百分比数值;
  • 两种方法的核心逻辑一致:对每个滚动窗口内的values集合,计算当前行points值在该集合中的相对位置;
  • 若不需要前3行的部分窗口结果,可将.complete = TRUE(slider)或移除partial = TRUE并设置fill = NA(zoo)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 00:53:39