使用带有 group_by 和 nest() 的 purrr 和 ggplot 时获取绘图的标题

Dav*_*vid 5 r ggplot2 dplyr purrr

我有以下示例:

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]])
}
Run Code Online (Sandbox Code Playgroud)

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

cam*_*lle 6

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

使用您的方法,您创建绘图列,将数据框保存到变量中,然后map2跨越绘图的列表列和carbs的向量,为每个绘图添加一个标题。然后你可以从结果列表打印任何物品,或把它们打印所有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)
Run Code Online (Sandbox Code Playgroud)

为简洁起见删除了额外的图

另一个似乎更直接的选项是将数据框拆分为数据框列表,然后根据需要为每个数据框创建图。

一些优点:调用split将 的每个值carb作为相应列表项的名称,您可以使用 轻松访问它imap,并将其保留到plots2列表中(请参阅下面我如何按名称打印绘图)。您也可以一步完成。我也很难处理嵌套数据,因为我更希望能够看到数据框,您可以通过打印出数据框的拆分列表来做到这一点。

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

plots2[["4"]]
Run Code Online (Sandbox Code Playgroud)

与第一种方法一样,您可以使用walk(plots2, print).


dyl*_*njm 6

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

library(tidyverse)

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

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

编辑:我删除了情节只是为了不挤满页面。在这种情况下,imap()允许我们在迭代时访问索引和值。如果您不想在标题中包含情节编号,那么map()就可以了。请注意,我还使用group_split()了最新版本的library(dplyr). 此外,在您的示例中,您创建了 ggplots 的 tibble,如果您正在执行更复杂的编码,这很好,很花哨,但在仅创建绘图的情况下,上述方法效果很好并且更容易理解。如果您想开发更复杂的图,您可以推断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)
Run Code Online (Sandbox Code Playgroud)