2

I've been messing around with this for some time. I recently started using the quantmod package to perform analytics on stock prices.

I have a ticker vector that looks like the following:

> tickers 
 [1] "SPY" "DIA" "IWM" "SMH" "OIH" "XLY" "XLP" "XLE" "XLI" "XLB" "XLK" "XLU" "XLV"    
[14] "QQQ"   
> str(tickers)   
 chr [1:14] "SPY" "DIA" "IWM" "SMH" "OIH" "XLY" "XLP" "XLE" ...   

I wrote a function called myX to use in a lapply call to save prices for every stock in the vector tickers. It has the following code:

myX <- function(tickers, start, end) { 
require(quantmod) 
getSymbols(tickers, from=start, to=end) 
} 

I call lapply by itself

library(quantmod) lapply(tickers,myX,start="2001-03-01", end="2011-03-11")

> lapply(tickers,myX,start="2001-03-01", end="2011-03-11") 
[[1]] 
[1] "SPY" 

[[2]] 
[1] "DIA" 

[[3]] 
[1] "IWM" 

[[4]] 
[1] "SMH" 

[[5]] 
[1] "OIH" 

[[6]] 
[1] "XLY" 

[[7]] 
[1] "XLP" 

[[8]] 
[1] "XLE" 

[[9]] 
[1] "XLI" 

[[10]] 
[1] "XLB" 

[[11]] 
[1] "XLK" 

[[12]] 
[1] "XLU" 

[[13]] 
[1] "XLV" 

[[14]] 
[1] "QQQ" 

That works fine. Now I want to merge the Close prices for every stock into an object that looks like

#            BCSI.Close WBSN.Close NTAP.Close FFIV.Close SU.Close 
# 2011-01-03      30.50      20.36      57.41     134.33    38.82 
# 2011-01-04      30.24      19.82      57.38     132.07    38.03 
# 2011-01-05      31.36      19.90      57.87     137.29    38.40 
# 2011-01-06      32.04      19.79      57.49     138.07    37.23 
# 2011-01-07      31.95      19.77      57.20     138.35    37.30 
# 2011-01-10      31.55      19.76      58.22     142.69    37.04 

Someone recommended I try something like the following:

ClosePrices <- do.call(merge, lapply(tickers, function(x) Cl(get(x))))

However I tried various combinations of this without any success. First I tried just calling lapply with Cl(x)

>lapply(tickers,myX,start="2001-03-01", end="2011-03-11") Cl(myX)))

> lapply(tickers,myX,start="2001-03-01", end="2011-03-11") Cl(x)))
Error: unexpected symbol in "lapply(tickers,myX,start="2001-03-01", end="2011-03-11") Cl"
> 
> lapply(tickers,myX(x),start="2001-03-01", end="2011-03-11") Cl(x)))
Error: unexpected symbol in "lapply(tickers,myX(x),start="2001-03-01", end="2011-03-11") Cl"
> 
> lapply(tickers,myX(start="2001-03-01", end="2011-03-11") Cl(x)
Error: unexpected symbol in "lapply(tickers,myX(start="2001-03-01", end="2011-03-11") Cl"
> lapply(tickers,myX(start="2001-03-01", end="2011-03-11") Cl(x))
Error: unexpected symbol in "lapply(tickers,myX(start="2001-03-01", end="2011-03-11") Cl"
>

Any guidance would be kindly appreciated.

Joshua Ulrich
  • 173,410
  • 32
  • 338
  • 418
codingknob
  • 11,108
  • 25
  • 89
  • 126
  • 2
    If you're going to cross-post, please at least provide a link to [your other posts](http://r.789695.n4.nabble.com/pass-character-vector-in-instrument-field-of-get-hist-quote-function-td3350779.html#a3431118). – Joshua Ulrich Apr 07 '11 at 00:54

3 Answers3

4

As I said in my reply on R-help, getSymbols is vectorized, so there's no need to loop over tickers. You don't need your myX function and the lapply call is completely unnecessary / redundant.

The code in my original answer works. Why are you trying other combinations?

tickers <- c("SPY","DIA","IWM","SMH","OIH","XLY",
             "XLP","XLE","XLI","XLB","XLK","XLU")
getSymbols(tickers, from="2001-03-01", to="2011-03-11")
ClosePrices <- do.call(merge, lapply(tickers, function(x) Cl(get(x))))
head(ClosePrices)
#            SPY.Close DIA.Close IWM.Close SMH.Close OIH.Close XLY.Close
# 2001-03-01    124.60    104.68     94.80     44.60     87.45     26.10
# 2001-03-02    123.61    104.80     95.05     45.34     91.20     26.30
# 2001-03-05    124.74    105.57     94.70     47.01     92.86     26.02
# 2001-03-06    126.08    106.15     96.10     49.59     94.34     26.68
# 2001-03-07    126.98    107.45     96.60     49.20     97.36     27.34
# 2001-03-08    127.12    108.61     95.80     49.20     97.59     27.78
#            XLP.Close XLE.Close XLI.Close XLB.Close XLK.Close XLU.Close
# 2001-03-01     26.39     32.10     29.28     21.14     28.80     31.62
# 2001-03-02     26.64     32.83     29.45     21.64     27.80     31.70
# 2001-03-05     26.54     33.01     29.82     22.03     28.40     31.64
# 2001-03-06     26.00     33.18     30.25     21.98     29.60     31.60
# 2001-03-07     25.83     33.89     30.61     22.63     29.64     31.45
# 2001-03-08     26.05     34.23     30.80     22.71     29.05     32.04
Joshua Ulrich
  • 173,410
  • 32
  • 338
  • 418
  • Thank you. I didnt know you can use function(x) and get(x) to refer to a previous call. This is why I was confused. I thought that function(x) was a holding name for a function that would execute and use tickers as input. I didnt know you could refer to a previously called function like the way you, JeffR and Dwin did. I have a LOT to learn about R. Thank you very much to the both of you. – codingknob Apr 07 '11 at 19:25
  • @user668624: it doesn't refer to a previous call (I'm not even sure what you mean by that). `function(x)` defines the function passed to `lapply`. `lapply` loops over `tickers` and passes each element of `tickers` to `function(x)`. `get(x)` returns the object with the name of the character string in `x` (the element from `tickers`). – Joshua Ulrich Apr 07 '11 at 19:34
  • so how does R know what function you are using to pass to lapply? R knew that getSymbols() was the function being passed to it and it looped over tickers. No? – codingknob Apr 07 '11 at 21:20
  • @user668624: R knows what function you are using to pass to `lapply` because you provide it as an argument to `lapply`. You passed `myX` (which called `getSymbols`) to `lapply` in your example and R evaluated `myX` for each element in `tickers`. But `getSymbols` loops over `tickers` internally, so you don't need to do it with `lapply`. – Joshua Ulrich Apr 07 '11 at 21:26
  • I am still confused. I passed myX because thats how I thought lapply worked. But in the solutions you guys provided you guys just used 'function(x)'. I copied and pasted your example word for word and R knew that it should use getSymbols. Was this because I ran getSymbols just prior to calling do.call(merge, lapply(tickers, function(x) Cl(get(x))))?? – codingknob Apr 07 '11 at 22:37
  • @user668624: `getSymbols` pulls the data for every element of `tickers` and creates objects in your global environment. `function(x)` doesn't know anything about `getSymbols`, but `get(x)` returns the object created by `getSymbols` from your global environment. – Joshua Ulrich Apr 07 '11 at 23:56
  • @JoshuaUlrich Sometimes `getSymbols` will be unable to download prices for a certain ticker and return an error saying `Error in download.file` which I believe occurs if a ticker is in-valid or doesn't exist. Wouldn't this be a good reason to loop through or use `apply` of some sort to have better error handling? – road_to_quantdom Dec 10 '15 at 08:42
  • @road_to_quantdom: It might be useful to call `getSymbols` on individual symbols from a loop if you want to do error handling. Using `apply` wouldn't make sense, because `apply` is meant to be called on a matrix/array and returns a similarly typed object. – Joshua Ulrich Dec 10 '15 at 11:43
2

Try using the env= arg and eapply

> mystocks <- new.env(hash=TRUE)

> getSymbols(c("AAPL","GOOG","YHOO"), env=mystocks)
<environment: 0x1023d1240>

> head( do.call(cbind,eapply(mystocks, Cl)) )
           AAPL.Close YHOO.Close GOOG.Close
2007-01-03      83.80      25.61     467.59
2007-01-04      85.66      26.85     483.26
2007-01-05      85.05      27.74     487.19
2007-01-08      85.47      27.92     483.58
2007-01-09      92.57      27.58     485.50
2007-01-10      97.00      28.70     489.46
Jeff R
  • 829
  • 4
  • 5
1

In order for merge to succeed with dataframes, there need to be column names in common. I suspected you wanted cbind rather than mergeanyway.

> ClosePrices <- do.call(cbind, lapply(tickers,  function(x) Cl(get(x))))
> head(ClosePrices)
           SPY.Close DIA.Close QQQ.Close
2001-03-01    124.60    104.68     48.80
2001-03-02    123.61    104.80     46.70
2001-03-05    124.74    105.57     47.55
2001-03-06    126.08    106.15     49.40
2001-03-07    126.98    107.45     49.42
2001-03-08    127.12    108.61     48.50

But as Joshua points out (and he should know) merge also works for the class of objects (xts) returned by getSymbols.

IRTFM
  • 258,963
  • 21
  • 364
  • 487
  • Good answer, but I'm not sure it's going to help. This question is a follow-up to the answer I gave on R-help (where I provided the same answer--almost verbatim). Also, `cbind` and `merge` do nearly the same thing to xts objects, which is what `getSymbols` returns by default. – Joshua Ulrich Apr 07 '11 at 01:13
  • Oh. ... I assumed his code (er, your code) wouldn't work, else-wise why post the question? I do see that `ClosePrices <- do.call(merge, lapply(tickers, function(x) Cl(get(x))))` does yield the same answer. – IRTFM Apr 07 '11 at 01:19
  • `merge` in xts/zoo is a bit different than `merge.default` in that the former merge by the index attribute and the latter merges by columns. – Joshua Ulrich Apr 07 '11 at 01:25
  • Thank you Dwin! All of your solutions worked. I have many hours, days and months ahead of me as I learn R... Thank you for your help. – codingknob Apr 07 '11 at 19:29