【问题标题】:Function to create and append ggplots to new list with names from existing list使用现有列表中的名称创建 ggplots 并将其附加到新列表的功能
【发布时间】:2018-02-28 21:48:57
【问题描述】:

我想创建一个包含绘图的命名列表。我从包含唯一 ID 的向量创建一个列表,用于过滤包含所有信息的主数据框。

然后我有一个函数,我在 lapply 中使用它来循环遍历唯一 ID 列表以过滤主数据框并创建图。然后我想将每个图附加到一个(最初)初始化的列表中,并且我希望列表条目的名称等于在 lapply 中传递的列表值。

我下面的代码创建了绘图,但是附加列表没有传递的列表 id 值的对应名称。

我有错误的方法吗?我见过使用 names(list) 等的问题/答案,但是传递给 lapply 的列表没有命名,我希望传递的列表条目成为新列表的名称。

提前致谢!

library(ggplot2)
library(dplyr)

unique_names = as.list(c("apple", "banana", "carrots"))
listy = list()
dframe = data.frame(x_var = seq(1:9)) %>% 
  mutate(y_var = x_var^3)
temp = data.frame(id = c("apple", "apple", "apple", "banana", "banana", "banana", "carrots", "carrots", "carrots"))
dframe = bind_cols(dframe,
                   temp)

fun_plots = function(my_list,
                     my_df,
                     my_appending_list) {
  a = filter(my_df,
             id == my_list)
  plt = ggplot() +
    geom_line(data = a,
              aes(x = x_var,
                  y = y_var))

  my_appending_list$my_list = plt
}

plot_list = lapply(unique_names,
                   fun_plots,
                   my_df = dframe,
                   my_appending_list = listy)

【问题讨论】:

    标签: r list ggplot2


    【解决方案1】:

    您可以避免编写函数并使用更多dplyr 魔法来改变列表。如果我理解正确,您希望“id”变量的每个值都有一个单独的绘图对象 - 如果是这样,您可以在“id”上执行group_by,然后为每个集合生成一个 ggplot 对象。方法如下

    plot_df <- dframe %>% 
      group_by(id) %>% 
      do(plot = ggplot(.data) + geom_line(aes(x = x_var, y = y_var)) + ggtitle(.data$id))
    plot_df
    #> Source: local data frame [3 x 2]
    #> Groups: <by row>
    #> 
    #> # A tibble: 3 x 2
    #>        id     plot
    #> *  <fctr>   <list>
    #> 1   apple <S3: gg>
    #> 2  banana <S3: gg>
    #> 3 carrots <S3: gg>
    

    您可以在 id 变量上设置一个 ggplot2。例如:

    ggplot(dframe) + geom_line(aes(x = x_var, y = y_var)) + facet_wrap(~ id)
    

    【讨论】:

    • 这真是太棒了,因为我不知道它的存在!谢谢!我实际上是在knitr(latex) 中进行绘图,这就是为什么我希望能够使用listname$plotname 调用这些绘图,这样我就可以直观地判断要从列表中绘制哪些绘图以及在哪里绘制。
    • 是的@Prevost,取决于你想要做什么,你可能会更好地使用一个情节。 facet_grid 和 facet_wrap(都是 ggplot2 的一部分)的好处是它们会根据您所关注的变量的值来标记每个面板 - 例如,您将拥有一个名为“apple”、“banana”的面板,和“胡萝卜”。除非您实际上需要三个单独的图,否则这可能会更容易。
    • 我想下次我会使用 dplyr do 函数在数据框中创建所有图,然后创建一个列表,其中每个条目等于行并调用ggplot 从那里...然后将列表的名称设置为唯一名称的数据框列...我相信有一种方法可以在不创建自定义函数的情况下通过使用已经存在的功能来完成所有这些!
    • 刚刚在另一个项目上工作,并尝试了两种效果很好的方法。如果试图在附录中显示更多的图(没有人阅读......),它非常适用
    【解决方案2】:

    您可以使用 dplyr group_by 来完成此操作:

    library(ggplot2)
    library(dplyr)
    
    unique_names = as.list(c("apple", "banana", "carrots"))
    listy = list()
    dframe = data.frame(x_var = seq(1:9)) %>% 
      mutate(y_var = x_var^3)
    temp = data.frame(id = c("apple", "apple", "apple", "banana", "banana", "banana", "carrots", "carrots", "carrots"))
    dframe = bind_cols(dframe,
                       temp)
    
    dframe <- group_by(dframe, id) %>% do(plots=ggplot(data=.) +
                                  aes(x=x_var, y=y_var) + geom_line() + ggtitle(unique(.$id)))
    
    mylist <- as.list(dframe$plots)
    
    mylist
    

    HTH 詹姆斯

    【讨论】:

      【解决方案3】:

      您可以取出my_appending_list 参数,因为它目前实际上并没有实现任何功能,您没有在函数中修改listy 对象。你可以这样做:

      fun_plots = function(my_list,
                           my_df) {
          a = filter(my_df,
                     id == my_list)
          plt = ggplot() +
              geom_line(data = a,
                        aes(x = x_var,
                            y = y_var))
      
          plt
      }
      
      plot_list = lapply(unique_names,
                         fun_plots,
                         my_df = dframe)
      names(plot_list) = unique_names
      

      【讨论】:

      • lapply 正在用 fun_plots 填充 alist,所以我不需要 listy...谢谢!有没有办法在fun_plots 中设置列​​表元素的名称?我认为不是因为 lapply 正在使用 fun_plots 创建列表元素...这种想法正确吗?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-23
      相关资源
      最近更新 更多