For-Loops for functions containing multiple argume

2019-09-19 06:57发布

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!

标签: r loops quantmod
2条回答
forever°为你锁心
2楼-- · 2019-09-19 07:42

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
查看更多
神经病院院长
3楼-- · 2019-09-19 07:42

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)

)
查看更多
登录 后发表回答