目标是使用3行的窗口和按最近行的顺序计算权重3、2、1的分组来计算加权平均.这与问题here类似,但权重不是按列给出的.此外,我真的很想使用frollsum(),因为我正在处理大量数据,需要它具有良好的性能.

我有一个使用frollapply()的解决方案:

library(data.table)

# Your data
set.seed(1)
DT <- data.table(group = rep(c(1, 2), each = 10), value = round(runif(n = 20, 1, 5)))

weights <- 1:3
k <- 3

weighted_average <- function(x) {
  sum(x * weights[1:length(x)]) / sum(weights[1:length(x)])
}

# Apply rolling weighted average
DT[, wtavg := shift(frollapply(value, k, weighted_average, align = "right", fill = NA)), 
   by = group]

DT 
#>     group value    wtavg
#>  1:     1     2       NA
#>  2:     1     2       NA
#>  3:     1     3       NA
#>  4:     1     5 2.500000
#>  5:     1     2 3.833333
#>  6:     1     5 3.166667
#>  7:     1     5 4.000000
#>  8:     1     4 4.500000
#>  9:     1     4 4.500000
#> 10:     1     1 4.166667
#> 11:     2     2       NA
#> 12:     2     2       NA
#> 13:     2     4       NA
#> 14:     2     3 3.000000
#> 15:     2     4 3.166667
#> 16:     2     3 3.666667
#> 17:     2     4 3.333333
#> 18:     2     5 3.666667
#> 19:     2     3 4.333333
#> 20:     2     4 3.833333

创建于2023-11-27,共reprex v2.0.2

推荐答案

可能不是最优的方法(我会研究RCPP),但只需使用Frollsum三次即可显著提高速度:

shift((frollsum(value, 3) + frollsum(value, 2) + frollsum(value, 1)) / 6)

注意,frollsum(value, 1)可以被value代替.

另一种(似乎)更快、更简单的 Select :

(c(shift(value, 3) + 2 * shift(value, 2) + 3 * shift(value, 1)) / 6,

标杆

set.seed(1)
n = 1000000
groups = 1:1000
DT <- data.table(group = rep(groups, each = n/length(groups)), value = round(runif(n = n, 1, 5)))


bench::mark(
  A = {
    DT[, shift(frollapply(value, k, weighted_average, align = "right", fill = NA)), 
   by = group]
  },
  B = {
    DT[, shift((frollsum(value, 3) + frollsum(value, 2) + value) / 6),
       by = group]
  }
)

#   expression      min   median `itr/sec` mem_alloc `gc/sec` n_itr  n_gc total_time
# 1 A             1.75s    1.75s     0.570    46.7MB     34.2     1    60      1.75s
# 2 B           80.38ms  85.72ms     9.24     77.4MB     12.9     5     7   541.13ms

R相关问答推荐

R形式的一维数字线/箱形图样式图表

使用对管道内单元格的引用生成新变量

为什么当我try 在收件箱中使用合并功能时会出现回收错误?

ggplot geom_smooth()用于线性回归虚拟变量-没有回归线

使用R中的Shapetime裁剪格栅文件

derrr mutate case_when grepl不能在R中正确返回值

为什么舍入POSIXct会更改能力以匹配等效的POSIXct?

使用R闪光显示所有数据点作为默认设置

为了网络分析目的,将数据框转换为长格式列联表

找出二叉树中每个 node 在R中的深度?

如何读取CSV的特定列时,给定标题作为向量

2个Rscript.exe可执行文件有什么区别?

方法::slotName如何处理非类、非字符的参数?

如何指定我的函数应该查找哪个引用表?

按多列统计频次

如何计算每12行的平均数?

自定义交互作用图的标签

在鼠标悬停时使用Plotly更改geom_point大小

有没有办法将勾选/审查标记添加到R中的累积关联图中?

如果极点中存在部分匹配,则替换整个字符串