【问题标题】:How to extract every ggplot2 plot from a nested list如何从嵌套列表中提取每个 ggplot2 图
【发布时间】:2019-09-07 22:54:28
【问题描述】:

创建大型嵌套列表以跟踪使用ggplot2 创建的图通常很方便。

例如,以下是我如何将少量图存储在一个大图列表中的方法,其中包含主题和子主题的子列表。

summary_plots

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

如何从整个列表中提取所有 ggplot2 绘图对象?我希望能够创建一个“平面”的单级列表,其中包含原始列表中包含的所有图。


这是一个简单的示例列表:

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

所需的结果相当于创建如下列表:

list('Demographics.Socioeconomic.Income' = generic_plot,
     'Demographics.Socioeconomic.Education' = generic_plot,
     ...)

【问题讨论】:

  • 我不认为这是特定于 ggplot 对象的列表,我认为这只是扁平化嵌套列表的问题,例如这里:stackoverflow.com/q/48443179/5325862
  • 感谢您分享该帖子。这里的问题是ggplot2 对象本身就是列表(is.list(generic_plot) is TRUE),因此在不取消列出或展平ggplot2 对象本身的情况下提取它们可能会很棘手。而且我认为ggplot2 对象是如此常见的用例,我认为将其作为自己的问题并不过分。
  • 是的,它们是列表使得简单的unlist 调用不起作用。
  • 由于 ggplot 对象具有类“ggplot”,因此这里可行的方法可能是递归遍历列表的级别,提取类等于“ggplot”的每个对象,并将结果作为ggplot 对象的扁平化列表。

标签: r ggplot2


【解决方案1】:

@MichaelThe code written in this answer 将完成此操作,只需稍作修改。

如果我们将morelists &lt;- ... 行中的class 检查更改为仅在类包含'list' 包含类'gg' 时才展平,那么它不会展平绘图,并将返回 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"

【讨论】:

  • 我使用 R 多年,但从未听说过 Recall()。很好的用例,我在尝试解决这个问题时遇到了问题,因为显然,list.flatten(summary_plots, classes = "ggplot") 什么都不做,list.flatten(summary_plots, classes = "gg") 产生不正确的结果(返回一个子ggplot 对象)。这个函数似乎只查看对象的第一类。
  • 感谢@divibisan 的回答。我已经将它改编成带有 Roxygen2 文档的函数,因此它可以巧妙地合并到 R 包中。任何想要使用它的人都可以在这里使用它:gist.github.com/bschneidr/3f9862b8856f87d2b8f8a24878f76cc9
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-30
  • 2021-09-17
  • 2021-08-20
  • 1970-01-01
  • 1970-01-01
  • 2023-04-04
相关资源
最近更新 更多