在我第一次尝试使用 RI 时,我猜想编写了两个性能不是很好的函数,如果我能收到一些关于如何使它们更具性能(矢量化)的提示,我将不胜感激。这两个函数最后都带有“测试用例”。
第一个函数采用两个时间序列 xts 对象 x 和 y 并返回一个序列,其中包含有关 x 高于/低于 y 天数的数据。
require('xts')
require('quantmod')
countDaysBelowOrAbove <- function(x, y) {
x <- try.xts(x, error=as.matrix)
y <- try.xts(y, error=as.matrix)
if(is.xts(x) && is.xts(y)) {
xy <- cbind(x,y)
} else {
xy <- cbind( as.vector(x), as.vector(y) )
}
# Count NAs, ensure they're only at beginning of data, then remove.
xNAs <- sum( is.na(x) )
yNAs <- sum( is.na(y) )
NAs <- max( xNAs, yNAs )
if( NAs > 0 ) {
if( any( is.na(xy[-(1:NAs),]) ) ) stop("Series contain non-leading NAs")
}
resultDaysLower <- x
resultDaysHigher <- x
resultDaysLower[!is.na(resultDaysLower)]<-0
resultDaysHigher[!is.na(resultDaysHigher)]<-0
series<-cbind(xy, resultDaysLower, resultDaysHigher)
colnames(series) <- c(names(xy), "cumDaysLower", "cumDaysHigher")
daysLower = 0
daysHigher = 0
for (i in 1:NROW(xy)) {
if (!(is.na(series[,1][i]) | is.na(series[,2][i]))) {
if (series[,1][i] >= series[,2][i]) {
daysLower = 0
daysHigher = daysHigher + 1
}
else {
daysHigher = 0
daysLower = daysLower + 1
}
}
else {
daysLower = 0
daysHigher = 0
}
series$cumDaysLower[i] = daysLower
series$cumDaysHigher[i] = daysHigher
}
return(series)
}
getSymbols("SPY", from='2005-01-01')
SPYclose = Cl(SPY)
getSymbols("QQQQ", from='2005-01-01')
QQQQclose = Cl(QQQQ)
testData = countDaysBelowOrAbove(SPYclose, QQQQclose)
我希望获得性能优化帮助的第二个功能如下。该函数将 xts 对象系列和表示间隔长度的 xts 对象作为参数,以计算指定时间的系列的最小值。该函数返回具有指定窗口的序列的计算最小值,用于以长度为单位的最小计算集。
minimumWithVaryingLength<-function(series, lengths) {
series <- try.xts(series, error=as.matrix)
lengths <- try.xts(lengths, error=as.matrix)
if(is.xts(series) && is.xts(lengths)) {
serieslengths <- cbind(series,lengths)
} else {
serieslengths <- cbind( as.vector(series), as.vector(lengths) )
}
# Count NAs, ensure they're only at beginning of data, then remove.
seriesNAs <- sum( is.na(series) )
lengthsNAs <- sum( is.na(lengths) )
NAs <- max( seriesNAs, lengthsNAs )
if( NAs > 0 ) {
if( any( is.na(serieslengths[-(1:NAs),]) ) ) stop("Series contain non-leading NAs")
}
result <- series
result[!is.na(result)]<-0
for (i in 1:NROW(serieslengths)) {
if (lengths[i] > 0) {
result[i] <- runMin(series, n=lengths[i], cumulative=FALSE)[i]
}
else {
result[i] <- 0
}
}
return(result)
}
getSymbols("SPY", from='2005-01-01')
SPYclose = Cl(SPY)
getSymbols("QQQQ", from='2005-01-01')
QQQQclose = Cl(QQQQ)
numDaysBelow = countDaysBelowOrAbove(SPYclose, QQQQclose)
test = minimumWithVaryingLength(SPYclose, numDaysBelow)
提前感谢您的帮助。
亲切的问候,萨摩。