问题
i have the following problem: I have got a custom defined function in R, which should get finance data (using quantmod); Now that i am thinking about that i maybe want to get several companies' stock prices or so i would it find more convenient if i can have a dataframe which contains the arguments of my function and a loop just goes through all the parts of the data frame and then saves the results into my environment (or a specific new dataframe or whatever).
The relevant parts of my code:
#Define Custom Function to get Data
pull = function(abbreviation,from,to){
getSymbols(Symbols = abbreviation, from = as.Date(from), to = as.Date(to),env = .GlobalEnv, reload.Symbols = FALSE, verbose = FALSE, warnings = TRUE, src = "yahoo", symbol.lookup = TRUE, auto.assign = TRUE)
#return(abbreviation_data) ##This part did not work but that should not be the relevant one inn this function as the function itself works;
}
For testing i defined my data now which shall be looped:
abbreviation = c("MSFT","AAPL")
from = c("2010-01-01","2011-01-01")
to = c("2017-04-19","2017-04-19")
stocks = data.frame(abbreviation,from,to)
And now the problematic lines:
for (i in 1:nrow(stocks)){
pull(stocks[i,1],stocks[i,2],stocks[i,3])}
as you maybe already saw i am an absolute beginner in R; Hopefully you can give me an answer how i get this one working and how i can get it into an output like a dataframe or smth. like that (like the original getSymbols-function does)
Thank you for your help!
回答1:
We can create a new environment
abb1 <- new.env()
for(i in seq_along(abbreviation)) abb1[[abbreviation[i]]] <- getSymbols(abbreviation[i],
from = from[i], to = to[i])
lst <- mget(ls(envir = abb1))
names(lst)
#[1] "AAPL" "MSFT"
lapply(lst, head, 3)
#$AAPL
# AAPL.Open AAPL.High AAPL.Low AAPL.Close AAPL.Volume AAPL.Adjusted
#2011-01-03 325.64 330.26 324.84 329.57 111284600 42.69894
#2011-01-04 332.44 332.50 328.15 331.29 77270200 42.92178
#2011-01-05 329.55 334.34 329.50 334.00 63879900 43.27289
#$MSFT
# MSFT.Open MSFT.High MSFT.Low MSFT.Close MSFT.Volume MSFT.Adjusted
#2010-01-04 30.62 31.10 30.59 30.95 38409100 25.55549
#2010-01-05 30.85 31.10 30.64 30.96 49749600 25.56374
#2010-01-06 30.88 31.08 30.52 30.77 58182400 25.40686
回答2:
Here's a solution that uses apply
with MARGIN = 1
to run your function over the rows of stocks
.
apply(stocks, 1, function(x)
getSymbols(Symbols = x["abbreviation"],
from = as.Date(x["from"]),
to = as.Date(x["to"]),
src = "yahoo",
env = .GlobalEnv,
reload.Symbols = FALSE,
verbose = FALSE,
warnings = TRUE,
symbol.lookup = TRUE,
auto.assign = TRUE)
)
As getSymbols
does by default, that code creates new objects in your working environment corresponding to the symbols you wanted.
If you're going to iterate other functions over the resulting data frames, you'll probably want to use lapply
instead, having getSymbols
return the results to a list in which each item corresponds to one of your symbols. Here's some code that does that:
# lapply works best on a list, so we can use another call to lapply to create
# a list of rows from stocks
mylist <- lapply(lapply(seq(nrow(stocks)), function(i) stocks[i,]), function(x)
# because the elements of the list we just created are data frames, we need
# to tweak the indexing to work with column names, so we add leading commas
getSymbols(Symbols = as.character(x[,"abbreviation"]),
from = as.Date(x[,"from"]),
to = as.Date(x[,"to"]),
src = "yahoo",
env = .GlobalEnv,
reload.Symbols = FALSE,
verbose = FALSE,
warnings = TRUE,
symbol.lookup = TRUE,
# here's the other change, so results go to list instead of env
auto.assign = FALSE)
)
来源:https://stackoverflow.com/questions/43573018/for-loops-for-functions-containing-multiple-arguments-r