Search code examples
rloopsquantmod

For-Loops for functions containing multiple arguments (R)


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!


Solution

  • 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)
    
    )