2014-10-29 46 views
1

我正在從雅虎導入一些股票數據,並希望將每日範圍計算爲高 - 低。然後我想把每個股票的範圍放在一個單獨的xts對象中。下面的代碼實現了這一點,但似乎對我來說非常複雜。在quantmod上使用lapply,直接轉到xts對象?

問題始於lapply。我得到了一個xts對象列表,但需要使用[[]]來引用單個對象的「下一層」。如果我可以引用每個xts對象作爲引號[我],我可以繼續使用apply函數而不是for循環。我嘗試使用sapply而不是lapply,但得到一個錯誤,「數組中的錯誤(r,dim = d,dimnames = if(!(is.null(n1 < - names(x [[1L]]))&: 'dimnames'[1]的長度不等於數組範圍「

此外,我討厭在第二個for循環中使用的練習,range還不存在,所以我需要創建它,方式似乎擊敗循環的目的。有沒有更好的辦法呢?我也想避免創建一個空的XTS對象作爲我知道這是不是好的做法無論是。

require(quantmod) 
tickers <- c("ERX", "EWJ", "EWW", "EWZ", "FAS", "FAZ") 

quotes <- lapply(tickers,function(x) getSymbols(x, src="yahoo", from="2014-10-10", auto.assign=FALSE)) 
names(quotes) <- tickers 

for (i in 1:length(quotes)){ 
    quotes[[i]] <- quotes[[i]][,2] - quotes[[i]][,3] 
    colnames(quotes[[i]]) <- paste(names(quotes)[i], "Range") 
} 

for (i in 1:length(quotes)){ 

    if (i == 1) {range <- quotes[[i]]} 

    else {range <- merge(range, quotes[[i]])} 
} 

謝謝。

回答

3

最簡單的方法是將數據遍歷環境中的所有對象與eapply存儲在一個環境,然後:

require(quantmod) 
tickers <- c("ERX", "EWJ", "EWW", "EWZ", "FAS", "FAZ") 
dataEnv <- new.env() 
getSymbols(tickers, env=dataEnv) 
# Calculate the range for all objects, 
# then merge all range columns into one object 
hl <- do.call(merge, eapply(dataEnv, function(x) Hi(x)-Lo(x))) 
# update the column names 
colnames(hl) <- gsub("(.*)High$", "\\1Range", colnames(hl)) 
+0

感謝Joshua。這是一個你創建的包,非常有幫助。 – mks212 2014-10-29 21:44:58

+0

@ user2926358:謝謝,但我沒有創建quantmod。傑夫瑞恩做到了。 – 2014-10-29 21:54:49

+0

夠公平的,謝謝xts! – mks212 2014-10-29 22:22:49