R 如何编写无止境/循环的滚动窗口?
我正在尝试创建一个滚动窗口,当窗口的尾部经过向量的末尾时,它会卷回向量的开始(假设向量长度始终至少与窗口大小一样大)。我可以通过无限次地重复向量,然后应用一个标准的滚动窗口来有效地实现这一点 也许有更好的名字来形容我想做的事,我不确定 我在R中工作,一种奇怪/被黑客攻击的方式是确保R填充矩阵的方式:R 如何编写无止境/循环的滚动窗口?,r,loops,R,Loops,我正在尝试创建一个滚动窗口,当窗口的尾部经过向量的末尾时,它会卷回向量的开始(假设向量长度始终至少与窗口大小一样大)。我可以通过无限次地重复向量,然后应用一个标准的滚动窗口来有效地实现这一点 也许有更好的名字来形容我想做的事,我不确定 我在R中工作,一种奇怪/被黑客攻击的方式是确保R填充矩阵的方式: # Number of windows n.reps <- 10 # Window Size time <- 12 # Vector I want to applying the w
# Number of windows
n.reps <- 10
# Window Size
time <- 12
# Vector I want to applying the window to
# Assume that the length of this vector is always >= window size
t.lvls <- c(0, 0, 0, 0.25, 0.25, 0.25, 0.75, 0.75, 0.75, 1, 1, 1)
# If I know n.reps ahead of time, I can simply create n.reps
# vectors with the appropriate frameshift by using
# matrix() and how it repeats values.
# This is effective but inelegant.
ref <- matrix(t.lvls, byrow=TRUE, nrow=n.reps, ncol=time+1)
use.lvls <- list() # holds the values in each window
for(i in 1:n.reps){
use.lvls[[i]] <- ref[i,-(time+1)]
}
如果需要无限的供应,请考虑迭代器< /P>
rolliter<-function(values,window) {
i<-0;
values<-c(values,values);
function() {i<<-i%%window+1;values[i:(i+window-1)]}}
rolliter基于@nongkrong的%%
建议,我编写了以下函数:
f5 <- function(){
len.tlvl <- length(t.lvls)
vals <- (1:time + rep(0:(n.reps-1), each=time))%%len.tlvl
use.inds <- matrix(vals, nrow=time)
use.inds[use.inds==0] <- len.tlvl
matrix(t.lvls[use.inds], nrow=time)
}
我修改了它,使输出是一个矩阵
(我知道这不是我最初的“预期输出”的格式,但我发现这不重要)。请注意,f6
函数在t.lvls
的长度小于time
时不起作用(同样,在我的原始问题中不是要求)
比较这两种方法的计算时间:
> microbenchmark(f5(), f6())
Unit: microseconds
expr min lq mean median uq max neval
f5() 33.789 36.436 39.28334 37.8530 40.3800 62.77 100
f6() 61.890 66.283 359.21862 69.9395 77.9295 28811.27 100
两者都很快并产生相似的结果,但是f5()
方法要快一点。用例是什么?R在许多情况下隐式执行向量循环。此外,一些特殊应用程序在不同的函数/包中处理,如filter
和zoo::rollappy
@A.Webb这些是我提供给仿真模型的参数值。我希望每个点都有一个参数值。但总的来说,无穷无尽的滚动窗口听起来像是可以用于多种用途的东西。@nongkrong我不知道你在想什么。。。精心制作?@nongkrong oops。。。修正代码和输出hx;请参阅我的答案/方法以了解时间比较。看起来我们都是受@nongkrong的启发,提到%%
f5 <- function(){
len.tlvl <- length(t.lvls)
vals <- (1:time + rep(0:(n.reps-1), each=time))%%len.tlvl
use.inds <- matrix(vals, nrow=time)
use.inds[use.inds==0] <- len.tlvl
matrix(t.lvls[use.inds], nrow=time)
}
rolliter<-function(values,window){
i<-0;
values<-c(values,values);
function() {i<<-i%%window+1;values[i:(i+window-1)]}
}
f6 <- function(){
nxt<-rolliter(t.lvls,12)
replicate(10,nxt(),simplify=T)
}
> microbenchmark(f5(), f6())
Unit: microseconds
expr min lq mean median uq max neval
f5() 33.789 36.436 39.28334 37.8530 40.3800 62.77 100
f6() 61.890 66.283 359.21862 69.9395 77.9295 28811.27 100