rollapply 报错:下标越界
Error in rollapply: subscript out of bounds
我想先描述一下我的问题:
我想做的是计算 24 小时内价格峰值的数量 window,而我拥有半小时的数据。
我看过所有 Whosebug 帖子,例如这个:
Rollapply for time series
(如果有更多相关的,请告诉我;))
因为我不能而且可能也不应该上传我的数据,这里是一个最小的例子:
我模拟一个随机变量,将其转换为 xts 对象,并使用用户定义的函数来检测 "spikes"(当然在这种情况下非常荒谬,但说明了错误)。
library(xts)
##########Simulate y as a random variable
y <- rnorm(n=100)
##########Add a date variable so i can convert it to a xts object later on
yDate <- as.Date(1:100)
##########bind both variables together and convert to a xts object
z <- cbind(yDate,y)
z <- xts(x=z, order.by=yDate)
##########use the rollapply function on the xts object:
x <- rollapply(z, width=10, FUN=mean)
该函数按预期工作:它取前 10 个值并计算平均值。
然后,我定义了一个自己的函数来查找峰值:峰值是局部最大值(高于它周围的 m 个点)并且至少与时间序列的平均值+h 一样大。
这导致:
find_peaks <- function (x, m,h){
shape <- diff(sign(diff(x, na.pad = FALSE)))
pks <- sapply(which(shape < 0), FUN = function(i){
z <- i - m + 1
z <- ifelse(z > 0, z, 1)
w <- i + m + 1
w <- ifelse(w < length(x), w, length(x))
if(all(x[c(z : i, (i + 2) : w)] <= x[i + 1])&x[i+1]>mean(x)+h) return(i + 1) else return(numeric(0))
})
pks <- unlist(pks)
pks
}
并且工作正常:回到示例:
plot(yDate,y)
#Is supposed to find the points which are higher than 3 points around them
#and higher than the average:
#Does so, so works.
points(yDate[find_peaks(y,3,0)],y[find_peaks(y,3,0)],col="red")
但是,使用 rollapply()
函数会导致:
x <- rollapply(z,width = 10,FUN=function(x) find_peaks(x,3,0))
#Error in `[.xts`(x, c(z:i, (i + 2):w)) : subscript out of bounds
我首先想到,好吧,可能会发生错误,因为它可能 运行 为第一个点设置负索引,因为 m
参数。遗憾的是,将 m
设置为零并不会改变错误。
这个错误我也试过查过,但是没有找到源头。
有人可以帮我吗?
编辑:尖刺图片:Spikes on the australian Electricity Market. find_peaks(20,50) determines the red points to be spikes, find_peaks(0,50) additionally finds the blue ones to be spikes (therefore, the second parameter h is important, because the blue points are clearly not what we want to analyse when we talk about spikes).
我仍然不完全确定您要找的是什么。假设给定 window 数据,您想要确定其中心是否大于 window 的其余部分,同时大于 window + h
那么您可以执行以下操作:
peakfinder = function(x,h = 0){
xdat = as.numeric(x)
meandat = mean(xdat)
center = xdat[ceiling(length(xdat)/2)]
ifelse(all(center >= xdat) & center >= (meandat + h),center,NA)
}
y <- rnorm(n=100)
z = xts(y, order.by = as.Date(1:100))
plot(z)
points(rollapply(z,width = 7, FUN = peakfinder, align = "center"), col = "red", pch = 19)
虽然在我看来,如果中心点大于它的邻居,它也必然大于局部平均值,所以如果 h >= 0
,这部分函数就不是必需的了。如果要使用时间序列的全局平均值,只需将 meandat
的计算替换为作为参数传递给 peakfinder
.
的预先计算的全局平均值
我想先描述一下我的问题: 我想做的是计算 24 小时内价格峰值的数量 window,而我拥有半小时的数据。
我看过所有 Whosebug 帖子,例如这个: Rollapply for time series
(如果有更多相关的,请告诉我;))
因为我不能而且可能也不应该上传我的数据,这里是一个最小的例子: 我模拟一个随机变量,将其转换为 xts 对象,并使用用户定义的函数来检测 "spikes"(当然在这种情况下非常荒谬,但说明了错误)。
library(xts)
##########Simulate y as a random variable
y <- rnorm(n=100)
##########Add a date variable so i can convert it to a xts object later on
yDate <- as.Date(1:100)
##########bind both variables together and convert to a xts object
z <- cbind(yDate,y)
z <- xts(x=z, order.by=yDate)
##########use the rollapply function on the xts object:
x <- rollapply(z, width=10, FUN=mean)
该函数按预期工作:它取前 10 个值并计算平均值。
然后,我定义了一个自己的函数来查找峰值:峰值是局部最大值(高于它周围的 m 个点)并且至少与时间序列的平均值+h 一样大。 这导致:
find_peaks <- function (x, m,h){
shape <- diff(sign(diff(x, na.pad = FALSE)))
pks <- sapply(which(shape < 0), FUN = function(i){
z <- i - m + 1
z <- ifelse(z > 0, z, 1)
w <- i + m + 1
w <- ifelse(w < length(x), w, length(x))
if(all(x[c(z : i, (i + 2) : w)] <= x[i + 1])&x[i+1]>mean(x)+h) return(i + 1) else return(numeric(0))
})
pks <- unlist(pks)
pks
}
并且工作正常:回到示例:
plot(yDate,y)
#Is supposed to find the points which are higher than 3 points around them
#and higher than the average:
#Does so, so works.
points(yDate[find_peaks(y,3,0)],y[find_peaks(y,3,0)],col="red")
但是,使用 rollapply()
函数会导致:
x <- rollapply(z,width = 10,FUN=function(x) find_peaks(x,3,0))
#Error in `[.xts`(x, c(z:i, (i + 2):w)) : subscript out of bounds
我首先想到,好吧,可能会发生错误,因为它可能 运行 为第一个点设置负索引,因为 m
参数。遗憾的是,将 m
设置为零并不会改变错误。
这个错误我也试过查过,但是没有找到源头。 有人可以帮我吗?
编辑:尖刺图片:Spikes on the australian Electricity Market. find_peaks(20,50) determines the red points to be spikes, find_peaks(0,50) additionally finds the blue ones to be spikes (therefore, the second parameter h is important, because the blue points are clearly not what we want to analyse when we talk about spikes).
我仍然不完全确定您要找的是什么。假设给定 window 数据,您想要确定其中心是否大于 window 的其余部分,同时大于 window + h
那么您可以执行以下操作:
peakfinder = function(x,h = 0){
xdat = as.numeric(x)
meandat = mean(xdat)
center = xdat[ceiling(length(xdat)/2)]
ifelse(all(center >= xdat) & center >= (meandat + h),center,NA)
}
y <- rnorm(n=100)
z = xts(y, order.by = as.Date(1:100))
plot(z)
points(rollapply(z,width = 7, FUN = peakfinder, align = "center"), col = "red", pch = 19)
虽然在我看来,如果中心点大于它的邻居,它也必然大于局部平均值,所以如果 h >= 0
,这部分函数就不是必需的了。如果要使用时间序列的全局平均值,只需将 meandat
的计算替换为作为参数传递给 peakfinder
.