根据带有 patchwork 包的参数显示图

Show plot according to argument with patchwork package

我正在尝试使用 patchwork 包编写一个函数,其中根据函数中传递的参数显示绘图。我尝试了下面的方法,将函数中未传递的对象设置为 NULL。但是,它仅在第一个对象不同于 NULL 时才有效。有什么想法吗?

# 1. PACKAGES

library(tidyverse)
library(patchwork)

# 2. DATA

data = starwars

# 3. FUNCTION

plot_people = function (homeworld = c("Tatooine", "Naboo", "Alderaan")) {

  p1 = if (is.element("Tatooine", homeworld)) {

    data %>%
    filter(homeworld == "Tatooine") %>%
    ggplot(aes(x = mass, y = height,
               label = ifelse(species == "Human", name, NA))) +
    geom_point() +
    geom_label()

  } else {

    NULL
  }

  p2 = if (is.element("Naboo", homeworld)) {

    data %>%
      filter(homeworld == "Naboo") %>%
      ggplot(aes(x = mass, y = height,
                 label = ifelse(species == "Human", name, NA))) +
      geom_point() +
      geom_label()

  } else {

    NULL
  }

  p3 = if (is.element("Alderaan", homeworld)) {

    data %>%
      filter(homeworld == "Alderaan") %>%
      ggplot(aes(x = mass, y = height,
                 label = ifelse(species == "Human", name, NA))) +
      geom_point() +
      geom_label()

  } else {

    NULL
  }

  # how to write this line in order to plot only objects in homeworld argument?
  p1 + p2 + p3

}

# 4. RESULTS

plot_people(homeworld = c("Naboo", "Tatooine"))

plot_people(homeworld = c("Naboo", "Alderaan"))
#> NULL

reprex package (v0.3.0)

于 2020-06-07 创建

由于您需要 运行 对 homeworld 的每个元素使用相同的代码,您可以使用 purrr::map (or lapply, if you prefer). This returns a list with an element for each iteration, here containing a plot (like p1, p2, etc.). This list can be reduced(或 Reduced)遍历它以迭代将每个元素与 +:

组合
library(tidyverse)
library(patchwork)

plot_people = function (homeworld = c("Tatooine", "Naboo", "Alderaan")) {

    plots <- map(homeworld, function(hw){
        starwars %>%
            filter(homeworld == hw) %>%
            ggplot(aes(x = mass, y = height,
                       label = ifelse(species == "Human", name, NA))) +
            geom_point() +
            geom_label()
    })

    reduce(plots, `+`)
}

plot_people(homeworld = c("Naboo", "Tatooine"))

plot_people(homeworld = c("Naboo", "Alderaan"))

或者,您可以编写 wrap_plots(plots),而不是 reduce(plots, `+`),使用 patchwork 中的 wrap_plots() 函数,该函数接受绘图列表。结果是一样的。

更一般地说,您应该在求助于拼凑之前考虑分面:

library(tidyverse)

plot_people = function (homeworld = c("Tatooine", "Naboo", "Alderaan")) {
    starwars %>%
        filter(homeworld %in% !!homeworld) %>%
        ggplot(aes(x = mass, y = height,
                   label = ifelse(species == "Human", name, NA))) +
        geom_point() +
        geom_label() + 
        facet_wrap(~homeworld)
}

plot_people(homeworld = c("Naboo", "Tatooine"))

plot_people(homeworld = c("Naboo", "Alderaan"))

请注意,使用这种方法,您可以免费获得漂亮的面板条标签,用于识别哪个行星。