【问题标题】:Get title for plots when using purrr and ggplot with group_by and nest()将 purrr 和 ggplot 与 group_by 和 nest() 一起使用时获取绘图的标题
【发布时间】:2019-07-16 16:59:27
【问题描述】:

我有以下例子:

df <- mtcars


plot <- df %>% 
  mutate(carb=as.character(carb)) %>% 
  group_by(carb) %>% 
    nest() %>% 
  mutate(plot=map(data, function(.x){ .x  %>%
      ggplot() +
      geom_bar(aes(mpg))
  }))

print(plot)

# A tibble: 6 x 3
  carb  data               plot    
  <chr> <list>             <list>  
1 4     <tibble [10 x 10]> <S3: gg>
2 1     <tibble [7 x 10]>  <S3: gg>
3 2     <tibble [10 x 10]> <S3: gg>
4 3     <tibble [3 x 10]>  <S3: gg>
5 6     <tibble [1 x 10]>  <S3: gg>
6 8     <tibble [1 x 10]>  <S3: gg>

for (i in 1:4){
  print(plots$plot[[i]])
}

问题: 1) 如何避免 for 循环并使用 map 函数打印绘图? 2)如何为地块添加标题。

【问题讨论】:

  • 你在哪里创建了n?在当前设置中,它将是 imapggtitle pass .y
  • 除非您需要在数据框中有一列 ggplot 对象,否则按 carb 拆分数据可能更直接,然后映射该数据框列表以绘制图表。比如这里:stackoverflow.com/q/45107404/5325862
  • 不太确定您要绘制的内容。
  • @akrun,卡米尔。这是一个复制粘贴错误。我自己的数据集有一个计数,我计算了 n。当我在电脑前时,我会删除问题并更新它。对不起!
  • 如果您编辑问题。我想绘制按碳水化合物分组的东西。并在一个标题。就像我说的 n 只是一个数字变量。

标签: r ggplot2 dplyr purrr


【解决方案1】:

您创建绘图的代码没有多大意义,但无论如何您将如何在不使用 for 循环的情况下提供标题和绘制图形:

library(tidyverse)

mtcars %>% 
  group_split(carb) %>% 
  imap(~ ggplot(data = .x) + 
        geom_bar(aes(mpg)) +
        labs(title = paste("Plot:", .y, "Carb:", unique(.x$carb))))

reprex package (v0.2.1) 于 2019 年 2 月 22 日创建

编辑:我删除了情节只是为了不拥挤页面。在这种情况下,imap() 允许我们在迭代时访问索引和值。如果您不想在标题中包含地块编号,那么map() 就可以了。请注意,我还使用了group_split(),它位于library(dplyr) 的最新版本中。此外,在您的示例中,您创建了一个 ggplots 的小标题,如果您正在执行更复杂的编码,这很好而且花哨,但在仅创建绘图的情况下,上述方法工作得很好并且更容易理解。如果您想开发更复杂的绘图,您可以将 ggplotmap() 函数中推断出来,并将其放入自己的函数中,如下所示:

plot_carb <- function(df){
  ggplot(data = df) + 
  geom_bar(aes(mpg)) + 
  labs(title = paste(Carb: unique(.x$carb))) + 
  theme_bw()
}

mtcars %>%
group_split(carb) %>%
map(plot_carb)

【讨论】:

  • @非常感谢!好吧,我只能接受一个答案,另一个答案是第一个,但我也从你的答案中学到了新东西。
【解决方案2】:

制作ggplot 对象的数据框列有点不寻常且麻烦,但如果适合这种情况,它可以工作。 (似乎geom_bar 对这些数据实际上没有意义,所以我切换到过滤后的碳水化合物子集的直方图)。

使用您的方法,您可以创建绘图列,将数据框保存到变量中,然后在绘图列表列和 carbs 的向量中使用map2,为每个绘图添加标题。然后您可以打印结果列表中的任何项目,或者使用mapwalk 将它们全部打印出来。

library(tidyverse)

df <- mtcars %>%
  filter(carb %in% c(1, 2, 4)) %>%
  mutate(carb = as.character(carb))

df_with_plots <- df %>% 
  group_by(carb) %>% 
  nest() %>% 
  mutate(plot = map(data, function(.x) { 
    .x  %>%
      ggplot() +
      geom_histogram(aes(mpg))
  }))

plots1 <- map2(df_with_plots$plot, df_with_plots$carb, ~(.x + labs(title = .y)))

# plots1[[1]] # would print out first plot in the list

walk(plots1, print)

为简洁起见删除了额外的情节

另一个看起来更简单的选项是将数据框拆分为数据框列表,然后根据需要为每个数据框创建图表。

一些优点:调用splitcarb 的每个值作为相应列表项的名称,您可以使用imap 轻松访问它,并且可以使用plots2 列表(见下文我如何按名称打印绘图)。您也可以一步完成。我也很难处理嵌套数据,因为我希望能够看到数据帧,您可以通过打印数据帧的拆分列表来做到这一点。

plots2 <- df %>%
  split(.$carb) %>%
  imap(function(carb_df, carb) {
    ggplot(carb_df) +
      geom_histogram(aes(mpg)) +
      labs(title = carb)
  })

plots2[["4"]]

和第一种方法一样,你可以用walk(plots2, print)打印出所有的图。

【讨论】:

  • @camille,好吧,这不是我……我只看到一个赞成票,那就是我自己。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-02-26
  • 2019-11-03
  • 2015-03-29
  • 1970-01-01
  • 2019-02-03
  • 1970-01-01
相关资源
最近更新 更多