如何在函数中执行 fct_drop(使用 tidy eval)?

How to do a fct_drop within a function (using tidy eval)?

使用钻石数据集...

正在尝试创建一个允许我在 x 轴上绘制切割或颜色的函数...

...但首先我想过滤所选列以仅显示一定数量的级别。

过滤器正常工作,但级别仍然存在...它们会显示在图表中。我需要在选定的列

上执行 fct_drop()

请参阅下面的代码以获取可重现的示例:

library(tidyverse)

diamonds <- diamonds %>% 
    mutate(cut = factor(cut),
         color = factor(color))

reduce_for_plot <- function(data, column, how_many_levels) {

  column2 <- enquo(column)
  of_interest <- unique(data[[deparse(substitute(column))]])[1:how_many_levels]

  data %>%
    filter(!! column2 %in% of_interest)

  # here is where I then do some kind of mutate... to fct_drop the selected column  

  # this line seems to work
  # value_to_put_in <- fct_drop(data[[deparse(substitute(column))]])

  # but this line doesn't  
  # data <- data %>% 
    # mutate(!! column = value_to_put_in)
}

diamonds %>% 
  reduce_for_plot(color, 1)

你快到了!您的代码中的问题是 R 不允许在 = 的 LHS 上使用 !。所以你需要使用假运算符 := 来代替。

reduce_for_plot <- function(data, column, how_many_levels) {
  col_expr <- enquo(column)
  col_name <- rlang::as_name(col_expr)

  of_interest <- unique(data[[col_name]])[1:how_many_levels]

  data <- data %>%
    filter(!!col_expr %in% of_interest)

  value_to_put_in <- fct_drop(data[[col_name]][of_interest])

  data %>%
    mutate(!!col_name := value_to_put_in)
}

如您所见,我已将所有 deparse(substitute(column)) 替换为 as_name(enquo(column))。但是,您可以通过在数据上下文中进行计算来完全避免这些,我认为这会产生更好的代码:

reduce_for_plot <- function(data, column, how_many_levels) {
  column <- enquo(column)

  data %>%
    filter(!!column %in% unique(!!column)[1:how_many_levels]) %>%
    mutate(!!column := fct_drop(!!column))
}