Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to extract every ggplot2 plot from a nested list

Tags:

r

ggplot2

It's often convenient to make large nested lists to keep track of plots created with ggplot2.

For example, here's how I might store a handful of plots in a large list of plots, with sublists for topics and sub-topics.

summary_plots

  1. $Demographics
    • Demographics$Socioeconomic$Household_Income_Plot
    • Demographics$Socioeconomic$Education_Plot
    • Demographics$Age_Plot
  2. $Product_Usage
    • Purchase_Frequency_Plot
    • ....

How can I extract all of the ggplot2 plot objects from this entire list? I'd like to be able to create a 'flat', one-level list containing all of the plots that were contained in the original list.


Here's a quick example list:

generic_plot <- ggplot(mtcars) + geom_point(aes(x = wt, y = mpg)) 

summary_plots <- list() 
summary_plots$Demographics$Socioeconomic$Income <- generic_plot 
summary_plots$Demographics$Socioeconomic$Education <- generic_plot 
summary_plots$Demographics$Age <- generic_plot 
summary_plots$Product_Usage$Purchase_Frequency <- generic_plot

The desired result would be the equivalent of creating a list like the following:

list('Demographics.Socioeconomic.Income' = generic_plot,
     'Demographics.Socioeconomic.Education' = generic_plot,
     ...)
like image 853
bschneidr Avatar asked Apr 17 '19 16:04

bschneidr


1 Answers

The code written in this answer by @Michael will accomplish this, with a small modification.

If we change the class check in the morelists <- ... line to only flatten if the class contains 'list' but does not contain the class 'gg', then it will not flatten the plots, and will return a flat list of ggplots.

flattenlist <- function(x){  
    morelists <- sapply(x, function(xprime) {
        'list' %in% class(xprime) & !('gg' %in% class(xprime))
    })
    out <- c(x[!morelists], unlist(x[morelists], recursive=FALSE))
    if(sum(morelists)){ 
        Recall(out)
    }else{
        return(out)
    }
}


plts <- flattenlist(summary_plots)

names(plts)

[1] "Demographics.Age"                    
[2] "Product_Usage.Purchase_Frequency"    
[3] "Demographics.Socioeconomic.Income"   
[4] "Demographics.Socioeconomic.Education"


lapply(plts, class)

$Demographics.Age
[1] "gg"     "ggplot"

$Product_Usage.Purchase_Frequency
[1] "gg"     "ggplot"

$Demographics.Socioeconomic.Income
[1] "gg"     "ggplot"

$Demographics.Socioeconomic.Education
[1] "gg"     "ggplot"
like image 141
divibisan Avatar answered Sep 28 '22 06:09

divibisan