Показать сюжет по аргументу с пакетом пэчворк
Я пытаюсь написать функцию с 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
Создано 07.06.2020 с помощью пакета REPEX (v0.3.0)
1 ответ
Поскольку вам нужно запустить один и тот же код для каждого элемента homeworld
, вы можете перебирать его с помощью purrr::map
(или lapply
, если хочешь). Это возвращает список с элементом для каждой итерации, здесь содержащий график (например,p1
, p2
, так далее.). Этот список может быть reduce
d (или Reduce
г) итеративно комбинировать каждый элемент с +
:
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"))
В качестве альтернативы вместо reduce(plots, `+`)
вы могли бы написать wrap_plots(plots)
, используя 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"))
Обратите внимание, что при таком подходе вы получаете красивые метки в виде полос на панели, определяющие, какая планета какая планета.