Reputation: 117
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
Upvotes: 1
Views: 271
Reputation: 55685
Here is a simpler way to do this
do.call('cbind', lapply(mget(stocks), function(d) d[,6]))
Explanation:
mget(stocks)
gets the three data frames as a listlapply
extracts the 6th column which contains the variable of interest.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.
Upvotes: 1
Reputation: 59335
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(...)
.
Upvotes: 0
Reputation: 11597
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"
Upvotes: 0