Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to automate a function containing for loop to take inputs dynamically in r?

I am trying to fetch data for some stocks using quantmod and it worked when I did for just 1 stock. But when I try to automate it for list of multiple Stock Symbols then I am not getting the results

Below Code works for getting just 1 Stock Symbol data by making it Static:

library(tidyverse)
library(quantmod)

# Creating Empty dataframe to collect final results
df_append <- setNames(data.frame(matrix(ncol = 8, nrow = 0)), 
                      c("Date", "Symbol", "Open","High","Low","Close","Volume","Adjusted"))

fetch_stock_data_fn <- function(){
  
  # Fetching Stock data for each symbol
  df_quant <- quantmod::getSymbols(Symbols = "SHREECEM.NS", src="yahoo",
                                   from = "2021-05-01",auto.assign = F) %>% 

  # converting time series to dataframe
              data.frame(as.matrix(.), Date=time(.), row.names = NULL) %>% 
    
  # Adding Symbol Column
              mutate(Symbol = "SHREECEM.NS",
                     Symbol = str_remove(Symbol, ".NS")) %>% 
              select(Date,Symbol,everything())

  # Removing String from Column Names
  for (col in 3: ncol(df_quant)){
    
      colnames(df_quant)[col] <- str_remove(colnames(df_quant)[col],"SHREECEM.NS.")
  }
  
  # Selecting Required columns only
  df_quant <- df_quant %>% 
              select(Date:Adjusted)
  
  # Append data to final dataframe
  df_append <- rbind(df_append,df_quant)
  
  return(df_append)
}

fetch_stock_data_fn()

Now when I try to modify this to accept stock symbol names for multiple symbols then I am not getting results. I think I am close to the solution but probably messing up with names in quotes while passing them as argument in the function call:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

library(tidyverse)
library(quantmod)

# Creating Empty dataframe to collect final results
df_append <- setNames(data.frame(matrix(ncol = 8, nrow = 0)), 
                      c("Date", "Symbol", "Open","High","Low","Close","Volume","Adjusted"))

fetch_stock_data_fn <- function(stock_name){
  
  # Fetching Stock data for each symbol
  df_quant <- quantmod::getSymbols(Symbols = {{stock_name}}, src="yahoo",
                                   from = "2021-05-01",auto.assign = F) %>% 

  # converting time series to dataframe
              data.frame(as.matrix(.), Date=time(.), row.names = NULL) %>% 
    
  # Adding Symbol Column
              mutate(Symbol = {{stock_name}},
                     Symbol = str_remove(Symbol, ".NS")) %>% 
              select(Date,Symbol,everything()) 

  # Removing String from Column Names
  for (col in 3: ncol(df_quant)){
    
      colnames(df_quant)[col] <- str_remove(colnames(df_quant)[col],paste0({{stock_name}},"."))
  }
  
  # Selecting Required columns only
  df_quant <- df_quant %>% 
              select(Date:Adjusted)
  
  # Append data to final dataframe
  df_append <- rbind(df_append,df_quant)
  
  return(df_append)
}

Calling Function:

test_vector <- c("SHREECEM.NS","ADANIPORTS.NS")

for (vec_count in 1: length(test_vector)){
  
  # print(test_vector[vec_count])
  fetch_stock_data_fn(test_vector[vec_count])
}

>Solution :

You could simplify your code a bit by using e.g. purrr::map_df to get rid of the rbind in your function and the for loop. Additionally I use rename_with to rename column names and finally there is IMHO no need for {{ as you are passing character strings:

library(tidyverse)
library(quantmod)

fetch_stock_data_fn <- function(stock_name) {
  # Fetching Stock data for each symbol
  df_quant <- quantmod::getSymbols(
    Symbols = stock_name, src = "yahoo",
    from = "2021-05-01", auto.assign = F
  )
  
  df_quant <- df_quant %>%
    # converting time series to dataframe
    data.frame(as.matrix(.), Date = time(.), row.names = NULL) %>%
    # Adding Symbol Column
    mutate(Symbol = str_remove(stock_name, ".NS")) %>%
    select(Date, Symbol, everything()) %>%
    # Removing String from Column Names
    rename_with(~ str_remove(.x, paste0(stock_name, "."))) %>%
    select(Date:Adjusted)

  return(df_quant)
}

test_vector <- c("SHREECEM.NS", "ADANIPORTS.NS")

df_append <- purrr::map_df(test_vector, fetch_stock_data_fn)

head(df_append)
#>         Date   Symbol     Open     High     Low    Close Volume Adjusted
#> 1 2021-05-03 SHREECEM 27500.00 28080.55 27327.6 27989.85  38741 27817.85
#> 2 2021-05-04 SHREECEM 28111.35 28111.50 27531.0 27753.30  41857 27582.75
#> 3 2021-05-05 SHREECEM 27850.00 28044.40 27713.3 27844.20  24250 27673.09
#> 4 2021-05-06 SHREECEM 27845.00 27946.25 27500.0 27736.20  33337 27565.75
#> 5 2021-05-07 SHREECEM 27847.00 27948.25 27700.0 27840.00  21548 27668.92
#> 6 2021-05-10 SHREECEM 27979.00 28035.15 27238.4 27309.95  49736 27142.12

count(df_append, Symbol)
#>       Symbol   n
#> 1 ADANIPORTS 338
#> 2   SHREECEM 338
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading