如何在函数中使用fct_drop(使用整齐的eval)?

问题描述 投票:2回答:1

使用钻石数据集......

试图创建一个允许我在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)
tidyeval
1个回答
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))
}
© www.soinside.com 2019 - 2024. All rights reserved.