在quantmod上使用lapply,直接使用xts对象?

时间:2014-10-29 21:13:44

标签: r xts quantmod

我正在从雅虎导入一些股票数据,并希望将每日范围计算为高 - 低。然后我想将每个股票的范围放在一个xts对象中。下面的代码实现了这一点,但对我来说似乎很复杂。

问题始于lapply。我得到了一个xts对象的列表,但需要引用单个对象"一层向下"使用[[]]。如果我可以将每个xts对象引用为引号[i],我可以继续使用apply函数而不是for循环。我尝试使用sapply而不是lapply但是得到了一个错误,"数组错误(r,dim = d,dimnames = if(!(is.null(n1< - names(x [[1L]]) )&   长度' dimnames' [1]不等于数组范围"

此外,我讨厌我在第二个for循环中使用的练习。范围还没有存在,所以我需要创建它但是以这种方式这样做似乎打败了循环的目的。有没有更好的办法?我也想避免创建一个空的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]])}
}

谢谢。

1 个答案:

答案 0 :(得分: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))