Only 'grobs' allowed in 'gList' error when calling grid.arrange inside a for loop

2k Views Asked by At

I'm trying to plot a price series and a return series using grid.arrange inside a for loop:

The set up:

library(tidyquant)

start_date <- as.Date('2022-01-01')
end_date <- as.Date('2022-03-31')

assets_list <- c('DGS30', 'T10Y2Y')

for (asset in assets_list){
  
  assign(paste('sym', asset, sep = '_'), tq_get(asset,
                                                from = start_date,
                                                to = end_date,
                                                get = 'economic.data') %>%
           # renames the generic 'price' column
           rename({{asset}} := price) %>%
           
           # casts from a tibble to a data frame
           as.data.frame() %>%
           
           # removes NA values
           na.omit()
  )
}

# joins the data frames together
df <- list(sym_DGS30, sym_T10Y2Y) %>%
  reduce(full_join, by='date')

# specifies only the desired columns in the data frame
df <- subset(df, select = c(date, DGS30, T10Y2Y))

# sorts the 'date' column
df <- df[order(df$date, decreasing = FALSE),] 

head(df)
        date DGS30 T10Y2Y
1 2022-01-03  2.01   0.85
2 2022-01-04  2.07   0.89
3 2022-01-05  2.09   0.88
4 2022-01-06  2.09   0.85
5 2022-01-07  2.11   0.89
6 2022-01-10  2.11   0.86

# adds a daily returns column for each asset
for (asset in assets_list){
  
  df <- df %>%
    tq_mutate(
      select = asset,
      mutate_fun = periodReturn,
      period = 'daily',
      col_rename = paste('daily_return', asset, sep = '_')
    )
}

head(df)
# A tibble: 6 x 5
  date       DGS30 T10Y2Y daily_return_DGS30 daily_return_T10Y2Y
  <date>     <dbl>  <dbl>              <dbl>               <dbl>
1 2022-01-03  2.01   0.85            0                    0     
2 2022-01-04  2.07   0.89            0.0299               0.0471
3 2022-01-05  2.09   0.88            0.00966             -0.0112
4 2022-01-06  2.09   0.85            0                   -0.0341
5 2022-01-07  2.11   0.89            0.00957              0.0471
6 2022-01-10  2.11   0.86            0                   -0.0337

First, I create some objects representing the price series:

plot_list_prices <- list()
for (asset in assets_list){
  
  plot_list_prices[[asset]] <- ggplot(df, aes(x = date, y = .data[[asset]])) +
    geom_line(color = 'darkblue') +
    ggtitle(paste('Time Series of', asset)) +
    xlab('Date') + ylab('Yield') +
    theme(plot.title = element_text(hjust = 0.5), axis.text.x = element_text(size = 7)) +
    scale_x_date(date_labels = '%b %y', date_breaks = '1 year', guide = guide_axis(check.overlap = TRUE))

}

Then, I create the objects representing the returns:

plot_list_returns <- list()
for (asset in assets_list){
  
  plot_list_returns[[asset]] <- ggplot(df, aes(x = date, y = .data[[paste0("daily_return_", asset)]])) +
    geom_line(color = 'darkblue') +
    ggtitle(paste('Daily Returns of', asset)) +
    xlab('Date') + ylab('Return') +
    theme(plot.title = element_text(hjust = 0.5), axis.text.x = element_text(size = 7)) +
    geom_hline(yintercept = 0, color = 'red') +
    scale_x_date(date_labels = '%b %y', date_breaks = '1 year', guide = guide_axis(check.overlap = TRUE))
  
}

Lastly, I want to render these plots using grid.arrange.

Doing it "manually" would look something like this:

grid.arrange(plot_list_prices$DGS30, plot_list_returns$DGS30, nrow=2, ncol=2, heights = c(2,1))
grid.arrange(plot_list_prices$T10Y2Y, plot_list_returns$T10Y2Y, nrow=2, ncol=2, heights = c(2,1))

But, because there are lots of these, I wrap them in a for loop, as follows:

for (asset in assets_list){
  grid.arrange(plot_list_prices[[paste0('$', asset)]],
               plot_list_returns[[paste0('$', asset)]],
               nrow=2, ncol=2, heights = c(2,1))
}

But, I'm getting the following error message:

Error in gList(list(wrapvp = list(x = 0.5, y = 0.5, width = 1, height = 1,  : 
  only 'grobs' allowed in "gList"

Can someone help with my grid.arrange syntax inside the for loop?

Thanks!

0

There are 0 best solutions below