我有一个包含以xts
格式存储的时间序列数据的列表。列表长度不等,只有日期/行的子集相交。
我希望迭代各种功能的列表组合 - 就这一点而言,我只想说我希望找到差异。
我能够为每个单一组合执行此操作,但无法获得更高阶函数来迭代批处理。
因此,例如,以下每项工作都是:
combn(c(1,2), 2, function(X) exData[[X[1]]] - exData[[X[2]]])
combn(c(1,3), 2, function(X) exData[[X[1]]] - exData[[X[2]]])
combn(c(2,3), 2, function(X) exData[[X[1]]] - exData[[X[2]]])
但是,我对高阶函数的尝试失败了:
combn(1:length(exData), 2, function(X) exData[[X[1]]] - exData[[X[2]]])
而是返回错误:Error in combn(1:length(exData), 2, function(X) exData[[X[1]]] - exData[[X[2]]]) : number of items to replace is not a multiple of replacement length
。
我不确定这意味着什么...
示例数据集可以如下构造:
set.seed(1)
dtime <- seq(Sys.Date(), length.out = 20, by='day')
exData <- replicate(4, runif(sample(9:12, 1)), simplify=FALSE)
exData <- lapply(exData,
function(x) xts(x,
order.by = sort(sample(dtime,
length(x)))[1:length(x)]))
重点是,并非所有日期都在列表中包含的每个xts
对象中,并且列表的长度不等。此时,我正在使用xts
对象规则来控制函数的应用程序 - 尽管这可能会在以后发生变化。
那么循环每个组合的适当方法是什么?这些组合由下面的每一列给出:
combos <- combn(1:4, 2)
R> combos
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 1 1 1 2 2 3
[2,] 2 3 4 3 4 4
注意:在现实生活中,每个xts
都有多列,并且允许应用于两个输入的函数的多样性。在@flodel的帮助下,我创建了以下函数,这些函数在操作后保留列名,并具有所需的灵活性。
funDiffName <- function(XTS, loc, ff){
# takes a list of XTS objects, a location pair (from combn), and the function to apply
# preserves names following the application of ff
ffxy <- ff(XTS[[loc[1]]], XTS[[loc[2]]])
names(ffxy) <- paste0(names(XTS[[1]]), "x", names(XTS[[2]]))
ffxy
}
SecPx_diff <- combn(1:(length(SecPx_l)), 2,
function(X) funDiffName(SecPx_l, X, `-`),
simplify = FALSE)
答案 0 :(得分:2)
错误来自R正在尝试将结果放入数组中,但这些部分具有不同的大小...解决方案是通过将simplify = FALSE
添加到combn
来请求列表打电话。
答案 1 :(得分:2)
您需要先cbind
他们。对于xts
,cbind
函数用它们的索引绑定两个xts。
combn(1:length(exData), 2, function(X) {
temp <- cbind(exData[[X[1]]], exData[[X[2]]])
temp <- (temp[, 1] - temp[, 2])
temp[!is.na(temp)]
}, simplify = FALSE)