我正在尝试组合一个将复制以下内容的函数
library(tidyverse)
library(magrittr)
library(data.table)
library(parallel)
library(RcppRoll)
windows <- (1:10)*600
df2 <- setDT(df_1, key=c("Match","Name"))[
,by=.(Match, Name), paste0("Period_", 1:10)
:= mclapply((1:10)*600, function(x) roll_mean(Dist, x))][]
Run Code Online (Sandbox Code Playgroud)
它根据分配给windows
我的工作函数创建一个滚动平均值,然后我会感觉有一个更好的方法,因为函数版本需要花费近30倍的时间来处理数据
dt_rolling <- function(df, the.keys, x, y, z, window){
df <- data.table(df)
setkeyv(df, the.keys)
df[,by=.(x,y), paste0("Period_", window) := mclapply(window, function(a) roll_mean(z, a))][]
}
df2 <- dt_rolling(df_1, the.keys=c('Match', 'Name'), df_1$Match, df_1$Name, df_1$Dist, windows)
Run Code Online (Sandbox Code Playgroud)
有问题的数据看起来像这样
> dput(head(df_1, 5))
structure(list(Match = c("BathH", "BathH", "BathH", "BathH",
"BathH"), Name = c("Alafoti Faosiliva", "Alafoti Faosiliva",
"Alafoti Faosiliva", "Alafoti Faosiliva", "Alafoti Faosiliva"
), Dist = c(0, 0, 0, 0, 0), Period_1 = c(NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_), Period_2 = c(NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_), Period_3 = c(NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_), Period_4 = c(NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_), Period_5 = c(NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_), Period_6 = c(NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_), Period_7 = c(NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_), Period_8 = c(NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_), Period_9 = c(NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_), Period_10 = c(NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_), Period_600 = c(NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_), Period_1200 = c(NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_), Period_1800 = c(NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_), Period_2400 = c(NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_), Period_3000 = c(NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_), Period_3600 = c(NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_), Period_4200 = c(NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_), Period_4800 = c(NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_), Period_5400 = c(NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_), Period_6000 = c(NA_real_, NA_real_,
NA_real_, NA_real_, NA_real_)), sorted = c("Match", "Name"), class = c("data.table",
"data.frame"), row.names = c(NA, -5L), .internal.selfref = <pointer: 0x10280cae0>)
Run Code Online (Sandbox Code Playgroud)
它可以扩展到超过2000万行,这就是我在data.table这里使用方法以及调查将其更改为函数的原因
编辑:
以下@ jangorecki关于添加data.table::frollmean()I 的回答与基于1,500,000行的数据集frollmean的Rcpp基于滚动平均函数的比较microbenchmark.
Unit: seconds
expr min lq mean median uq max neval cld
rcpp 1.056967 1.224827 1.374116 1.304310 1.467108 5.855003 1000 a
data.table 1.096122 1.306993 1.466128 1.389878 1.549299 9.287606 1000 b
Run Code Online (Sandbox Code Playgroud)
自v1.12.0版本以来,data.table中提供了快速滚动平均值.
以下查询将解决您的问题.
df_1[, paste0("Period_", windows) := frollmean(Dist, windows)]
Run Code Online (Sandbox Code Playgroud)