Question

I am trying to achieve the following

stocks <- c('AXP', 'VZ', 'V')
library('quantmod')
getSymbols(stocks)

Above command creates 3 data variables named AXP, VZ, and V

prices <- data.frame(stringAsFactors=FALSE)

Here I am trying to create a column with name as ticket (e.g. AXP) with data in The following should add 3 columns to the frame, names AXP, VZ, and V with data in AXP$AXP.Adjusted, VZ$VZ.Adjusted, V$V.Adjusted

for (ticker in stocks)
{
  prices$ticker <- ticker$ticker.Adjusted
}

How do I achieve this? R gives an error like this when I try this

Error in ticker$ticker.Adjusted : 
  $ operator is invalid for atomic vectors

Any ideas?

Thanks in advance

Was it helpful?

Solution

Here is a simpler way to do this

do.call('cbind', lapply(mget(stocks), function(d) d[,6]))

Explanation:

  1. mget(stocks) gets the three data frames as a list
  2. lapply extracts the 6th column which contains the variable of interest.
  3. do.call passes the list from (2) to cbind, which binds them together as columns.

NOTE: This solution does not take care of the different number of columns in the data frames.

OTHER TIPS

I did not understand your question before, now I think I understood what you want:

What you wrote does not work because the object ticker is character string. If you want to get the object named after that string, you have to evaluate the parsed text.

Try this:

for (ticker in stocks){
      prices <- cbind(prices, eval(parse(text=ticker))[,paste0(ticker, ".", "Adjusted")])

}

This will give you:

An ‘xts’ object on 2007-01-03/2014-01-28 containing:
  Data: num [1:1780, 1:4] 53.4 53 52.3 52.8 52.5 ...
 - attr(*, "dimnames")=List of 2
  ..$ : NULL
  ..$ : chr [1:4] "AXP.Adjusted" "AXP.Adjusted.1" "VZ.Adjusted" "V.Adjusted"
  Indexed by objects of class: [Date] TZ: UTC
  xts Attributes:  
List of 2
 $ src    : chr "yahoo"
 $ updated: POSIXct[1:1], format: "2014-01-29 01:06:51"

One problem you're going to have is that the three downloads have different number of rows, so binding them all into a single data frame will fail.

The code below uses the last 1000 rows of each file (most recent), and does not use loops.

stocks <- c('AXP', 'VZ', 'V')
library('quantmod')
getSymbols(stocks)

prices=do.call(data.frame,
               lapply(stocks,
                      function(s)tail(get(s)[,paste0(s,".Adjusted")],1000)))
colnames(prices)=stocks
head(prices)
#              AXP    VZ     V
# 2010-02-08 34.70 21.72 80.58
# 2010-02-09 35.40 22.01 80.79
# 2010-02-10 35.60 22.10 81.27
# 2010-02-11 36.11 22.23 82.73
# 2010-02-12 36.23 22.15 82.38
# 2010-02-16 37.37 22.34 83.45

Working from the inside out, s is the ticker (so, e.g., "AXP"); get(s) returns the object with that name, so AXP; get(s)[,paste0(s,".Adjusted")] is equivalent to AXP[,"AXP.Adjusted"]; tail(...,1000) returns the last 1000 rows of .... So when s="AXP", the function returns the last 1000 rows of AXP$AXP.Adjusted.

lapply(...) applies that function to each element in stocks.

do.call(data.frame,...) invokes the data.frame function with the list of columns returned by lapply(...).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top