在R中,为什么purrr的map2在绘图时忽略了group_by参数?

t40tm48m  于 2023-01-22  发布在  其他
关注(0)|答案(3)|浏览(141)

我有许多图需要创建,并按学生的级别划分。为此,我希望使用purrr包中的map2。我希望每个级别有一个图(总共4个图),但当我执行group_by时,该代码为每个学生创建一个图(16个唯一的图)。*如何让代码为每个年级而不是每个学生创建一个图?

#My data
library(dplyr)
my_data <- tibble(level = c(rep(c("Kindergarten", "1st", "2nd", "3rd"), 4)),
                  id = c(1:16),
                  score = c(81:96))
#My attempt at making one plot per level--makes 16 plots instead of 4

library(purrr)
library(stringr)
library(ggplot2)

#Extract information
levels <- my_data %>% pull(level) %>% as.character
scores <- my_data %>% pull(score)

#Make plots
my_plots <- map2(
  .x = levels,
  .y = scores,
  .f = ~{
    my_data %>%
      group_by(level) %>% # I don't know why this is being ignored
      ggplot(aes(x = .x, y = .y)) +
      geom_point() +
      ggtitle(str_glue("Score by {.x}"))
  }
)

my_plots #has 16 plots (one for each data point) instead of 4 (one for each level with each respective student represented)
gab6jxml

gab6jxml1#

请检查下面的代码,我更新了代码,只使用Map功能的水平,我们可以用来过滤我的数据
编号

library(purrr)
levels <- my_data$level %>% unique()

#Make plots
my_plots <- map(
  .x = levels,
  .f = ~{
    my_data %>%
      filter(level == .x) %>% # I don't know why this is being ignored
      ggplot(aes(x = id, y = score)) +
      geom_point() +
      ggtitle(str_glue("Score by {.x}"))
  }
)

my_plots #has 16 plots (one for each data point) instead of 4 (one for each level with each respective student represented)

输出

kmbjn2e3

kmbjn2e32#

我可以建议一种稍微不同的方法,它可以节省一些编码(用map代替map2,需要定义的变量更少,引用也更清晰)。
首先通过拆分数据框创建列表,然后为每个列表创建图。

library(tidyverse)
my_data <- tibble(level = c(rep(c("Kindergarten", "1st", "2nd", "3rd"), 4)),
                  id = c(1:16),
                  score = c(81:96))

my_data %>% 
  group_split(level) %>%
  ## or, which I prefer, with split (it makes a named list)
  # split(.$level) %>%
  map({
    ~ggplot(.x, aes(level, score)) +
  geom_point() +
  ggtitle(str_glue("Score by {unique(.x$level)}"))
  }) %>%
  ## just for demo purpose
  patchwork::wrap_plots()

创建于2023年1月18日,使用reprex v2.0.2

mzmfm0qo

mzmfm0qo3#

根据需求,我更愿意使用facet:

library(dplyr)
library(purrr)
library(ggplot2)
library(forcats)
my_data <- tibble(level = c(rep(c("Kindergarten", "1st", "2nd", "3rd"), 4)),
                  id = c(1:16),
                  score = c(81:96))

# fix level order
my_data$level <- fct_inorder(my_data$level)

# Single plot with facets by levels:
my_data %>% 
  ggplot(aes(x = id, y = score)) +
  geom_point() +
  facet_wrap(vars(level))

对于单独的绘图,拆分 Dataframe 本身似乎更自然。split()创建由拆分所用因子值命名的 Dataframe 列表(即本例中的level值)。此处使用imap()通过.y访问列表名称。

# Separte plots by levels
library(patchwork)
plots <- imap(split(my_data, my_data$level),
              ~ ggplot(.x, aes(x = id, y = score)) +
                geom_point() +
                ggtitle(.y)) 

# plots patched together to save some space
(plots[[1]] | plots[[2]]) / (plots[[3]] | plots[[4]])

创建于2023年1月18日,使用reprex v2.0.2

相关问题