2013-10-15 154 views
1

我有一個包含以xts格式存儲的時間序列數據的列表。列表長度不相等,只有日期/行的一部分相交。迭代包含不等長的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

您是否正在尋找具有相同時間戳的行中的差異? –

+0

@geektrader是的,我正在尋找具有相同時間戳的行之間的差異。 – ricardo

回答

2

這個錯誤來自一個事實,即R爲試圖把結果放到一個數組,而片有不同的大小...的解決方案是通過添加simplify = FALSEcombn呼叫請求列表。

+0

謝謝。我希望'simplified = FALSE'是默認的... – ricardo

2

您需要先登錄cbind。對於xtscbind函數通過它們的索引來綁定這兩個xt。

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)