1

我想制作一个使用ggplot并将facet_wrap函数变量传递给 facet by 的函数。

我可以使用带引号的参数执行以下操作。

library(tidyverse)

my_grid_plot <- function(facet_by){
  ggplot(mtcars, aes(wt, disp)) +
    geom_point() +
    facet_wrap(facet_by)
}

my_grid_plot(facet_by = 'am')  
my_grid_plot(facet_by = 'vs')  
my_grid_plot(facet_by = c('am', 'vs')) 

但是,我想使用未引用的参数来做到这一点,例如

# does not work yet; this is what I want
my_grid_plot(facet_by = am)  
my_grid_plot(facet_by = vs)  
my_grid_plot(facet_by = c(am, vs))

我知道我可以使用varswith facet_wrap,例如

ggplot(mtcars, aes(wt, disp)) +
  geom_point() +
  facet_wrap(vars(am, vs))

所以我可以做这样的事情

my_grid_plot2 <- function(facet_by){
  ggplot(mtcars, aes(wt, disp)) +
    geom_point() +
    facet_wrap(vars({{facet_by}}))
}

# works fine
my_grid_plot2(am)
my_grid_plot2(vs)

facet_by但如果是向量,那将不起作用。

# does not work; obscure error
my_grid_plot2(c(am, vs))

那么有没有办法得到我想要的上面的东西,即在哪里facet_by需要一个名称向量的单个变量名称?

4

2 回答 2

1

我不知道这是否是正确的或最好的方法,它似乎有点hacky,但我认为它可以完成工作。灵感来自https://stackoverflow.com/a/57709169/1009979

my_grid_plot3 <- function(facet_by){
  
  by_expr <- enexpr(facet_by)
  
  if(length(by_expr) == 1) {
    args_vars <- as.list(by_expr)
  } else {
    args_vars <- as.list(by_expr)[-1]
  }
  
  quoted_args_vars <- sapply(args_vars, quo_name)
  
  ggplot(mtcars, aes(wt, disp)) +
    geom_point() +
    facet_wrap(quoted_args_vars)
}

# this works
my_grid_plot3(am)
my_grid_plot3(vs)
my_grid_plot3(c(am, vs))
于 2020-10-08T18:01:22.133 回答
0

一种选择是让tidyselect繁重的工作:

my_grid_plot2 <- function(facet_by){
  by <- rlang::enexpr(facet_by) %>%
    tidyselect::eval_select(mtcars)

  ggplot(mtcars, aes(wt, disp)) +
    geom_point() +
    facet_wrap(names(by))
}

## All of the following now work as expected
my_grid_plot2(am)
my_grid_plot2(vs)
my_grid_plot2(c(am, vs))

my_grid_plot2('am')
my_grid_plot2('vs')
my_grid_plot2(c('am', 'vs'))

于 2021-06-19T17:40:43.327 回答