将dplyr::filter()作为参数输入函数

3

将dplyr::filter输入函数

如何创建一个函数,该函数将任何dplyr::filter作为输入,并返回满足筛选条件的行数?

我尝试了以下代码,但它并不起作用:

library(tidyverse)

filter_function <- function(dataset, filter_text) {
    dataset %>% filter_text %>% nrow() -> n_rows_satisfy_filter

    paste0( "Number of rows satisfying the filter: ", n_rows_satisfy_filter)
}

我在这里尝试将过滤器作为字符串输入:

filter_function(iris, "filter( Sepal.Length > 5 & Species == 'setosa' )" )

出现错误:
Error in quote(., filter_text) : 
  2 arguments passed to 'quote' which requires 1 

这个问题与在编程中使用dplyr filter()类似,但不是重复的,因为当前的问题试图改变整个过滤器,而不仅仅是静态过滤器的输入。

2个回答

3
尝试这段代码,eval会在envir指定的环境中评估expr参数并返回计算出的值。
library(tidyverse)

filter_function <- function(dataset, filter_text) {
  n_rows_satisfy_filter <- eval(parse(text = filter_text), envir = dataset) %>% nrow()
  paste0( "Number of rows satisfying the filter: ", n_rows_satisfy_filter)
}

filter_function(iris, "filter(dataset, Sepal.Length > 5 & Species == 'setosa' )" )

1
使用`tidyverse`,另一个选择是来自`rlang`的`parse_expr`。
library(dplyr)
filter_function <- function(dataset, filter_text) {
  eval(rlang::parse_expr(filter_text)) %>% 
         nrow() %>%
         paste0( "Number of rows satisfying the filter: ", .)
}

filter_function(iris, "filter(dataset, Sepal.Length > 5 & Species == 'setosa' )" )
#[1] "Number of rows satisfying the filter: 22"

有没有可能避免将数据集硬编码到字符串中,仍然使用tidyverse?例如 dataset %>% eval(parse_expr(filter_text)),其中filter_text类似于 filter( Sepal.Length > 5 & Species == 'setosa' ) - Rasmus Larsen
1
@RasmusLarsen 需要数据集的环境。 - akrun

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接