You could write those last two lines using get
(which converts symbol names to symbols), do.call
(which applies a function to a list), and lapply
(which creates a list from the results of a [different] function):
mergedData <- do.call(merge, lapply(symbolList, function(sym) { get(sym)[,6] }) )
colnames(mergedData) <- c("Apple", "Microsoft", "Tesla", "Google", "IBM")
But you could also simplify your whole process considerably by using auto.assign=FALSE
in getSymbols
. (I've also changed symbolList from a list to a named vector, which is really all you need.):
library(quantmod)
START <- '2013-09-03'
symbolList <- c(Apple="AAPL", Microsoft="MSFT", Tesla="TSLA", Google="GOOG", IBM="IBM")
dataList <- lapply(symbolList, function(sym) {
setNames(getSymbols(sym, src='yahoo', from=START, auto.assign=FALSE)[,6], names(sym))
})
mergedData <- do.call(merge, dataList)
Or if you want really dense code:
mergedData <- do.call(merge, lapply(symbolList, function(sym) {
setNames(getSymbols(sym, src='yahoo', from=START, auto.assign=FALSE)[,6], names(sym))
}))
Appendix - An explanation of the lapply call (in response to your comment)
In this line:
dataList <- lapply(symbolList, function(sym) {
setNames(getSymbols(sym, src='yahoo', from=START, auto.assign=FALSE)[,6], names(sym))
})
I've passed two arguments to lapply: the vector symbolList
(could have been a list) and a function function(sym) { ... }
. I could have passed a pre-defined function -- for example, if I wanted to count the number of characters in each symbol, I could have passed in nchar
:
lapply(symbolList, nchar)
and that would have been the same as calling
list(Apple=nchar(symbolList[[1]]), Microsoft=nchar(symbolList[[2]]), Tesla=nchar(symbolList[[3]]), Google=nchar(symbolList[[4]]), IBM=nchar(symbolList[[5]]))
where both return a list of the form
list(Apple=4, Microsoft=4, Tesla=4, Google=4, IBM=3)
But instead of using nchar
, I wrote my own function. This function returns things I want in place of the 4, 4, 4, 4, and 3 in the nchar
example. The function could be defined separately:
myfun <- function(sym) {
setNames(getSymbols(sym, src='yahoo', from=START, auto.assign=FALSE)[,6], names(sym))
}
And we could then have passed myfun
to lapply
to get the result we want:
dataList <- lapply(symbolList, myfun)
In this case, rather than 4, 4, 4, 4, and 3, we get a list of xts objects. We also could have constructed that same list this way:
dataList2 <- list(Apple=myfun(symbolList[[1]]), Microsoft=myfun(symbolList[[2]]), Tesla=myfun(symbolList[[3]]), Google=myfun(symbolList[[4]]), IBM=myfun(symbolList[[5]]))
but of course the lapply
version is cleaner and more flexible about the number and names of the list elements.
In practice, it's often a little clunky to first assign the function to some variable (myfun
in this case) and then pass the function to lapply
. So in my original answer I chose instead to define the function within the lapply
call, without ever giving it a name. myfun
and function(sym) { ... }
are equivalent function objects. Given that information, I hope you can now understand (or even modify) the lapply
call from my original answer, copied here:
dataList <- lapply(symbolList, function(sym) {
setNames(getSymbols(sym, src='yahoo', from=START, auto.assign=FALSE)[,6], names(sym))
})