Search code examples
rlistdplyrxts

Store XTS objects as data frames in a list in R


I wish to store some XTS objects as data frames within a list in R.

The XTS objects are stock price data collected using the tidyquant package, I need to convert these objects to data frames and store them in a list. I have one additional requirement, I only want to retain the index column and the closing price column for each stock.

I have tried using dplyr syntax to select the columns of interest but my code fails to select column indexes greater than 2

Error: Can't subset columns that don't exist.
x Locations 3 and 4 don't exist.
i There are only 2 columns.

This is the code I am using but I am struggling to understand how I can't select the closing price from my 'fortified' data frames

pacman::p_load(tidyquant,tidyverse,prophet)

tickers = c("AAPL","AMZN")

getSymbols(tickers, 
           from = '2015-01-01',
           to = today(),
           warnings = FALSE,
           auto.assign = TRUE)

dfList <- list()

for (i in tickers) {
  dfList[[i]] <- fortify.zoo(i) %>% 
    select(c(1,5))
  }

When I convert an individual XTS object to a data frame using fortify.zoo I can select the columns of interest but not when I loop through them.

fortify.zoo(AAPL) %>% select(c(1,5)) %>% head(n = 10)

Can anyone help me understand where I am falling down in my understanding on this issue please?


Solution

  • It is better to initialize a list with fixed length and name it with the tickers. In the OP's code, it is looping over the tickers directly, so each 'i' is the ticker name which is a string

    dfList <- vector('list', length(tickers))
    names(dfList) <- tickers
    

    As the i here is a string name of the object "AAPL" or "AMZN", we can use get to return the value of that object from the global env

    for (i in tickers) {
      dfList[[i]] <- fortify.zoo(get(i)) %>% 
                 select(c(1,5))
       }
    

    -check the dimensions

    sapply(dfList, dim)
    #    AAPL AMZN
    #[1,] 1507 1507
    #[2,]    2    2
    

    Another approach is mget to return all those objects into a list

    library(purrr)
    library(dplyr)
    dfList2 <-  mget(tickers) %>%
         map(~ fortify.zoo(.x) %>% 
                 select(1, 5))