【问题标题】:programming a filter in tidyverse using quoting使用引用在 tidyverse 中编程过滤器
【发布时间】:2018-08-03 20:42:14
【问题描述】:

我有一个带有成对变量的小标题:
- a_x, a_y,
- b_x, b_y,
- c_x, c_y 等等。

如何编写一个根据“a”、“b”或“c”进行过滤的函数。比如我想返回

filter(df, a_x != a_y) 

filter(df, b_x != b_y)

我正在使用 quosures,如中所述 https://dplyr.tidyverse.org/articles/programming.html, 但没有成功。

这是一个例子:

test <-tribble(~a_x, ~b_x, ~a_y, ~b_y,
1,2,1,2,
5,6,5,8,
9,8,11,8)

# that works
x <-quo(a_x)
y <-quo(a_y)
filter(test, !!x == !!y)
x <-quo(b_x)
y <-quo(b_y)
filter(test, !!x == !!y)

# but the function doesn't work
my <- function(df, var){
a <- paste0(quo_name(var), "_x")
b <- paste0(quo_name(var), "_y")
print(quo(filter(df, !!a == !!b)))
return(filter(df, !!a == !!b))
}
my(test, "a")
my(test, "b")

【问题讨论】:

    标签: r tidyverse


    【解决方案1】:

    当我们传递一个字符串时,它更容易转换为符号和评估

    library(dplyr)
    library(rlang)
    my <- function(df, var){
     a <- sym(paste0(var, "_x"))
     b <- sym(paste0(var, "_y"))
     df %>% 
         filter(!!a == !!b)
    
    } 
    
    
    my(test, "a")
    # A tibble: 2 x 4
    #    a_x   b_x   a_y   b_y
    #  <dbl> <dbl> <dbl> <dbl>
    #1     1     2     1     2
    #2     5     6     5     8
    my(test, "b")
    # A tibble: 2 x 4
    #    a_x   b_x   a_y   b_y
    #  <dbl> <dbl> <dbl> <dbl>
    #1     1     2     1     2
    #2     9     8    11     8
    

    如果 OP 也打算传递未引用的参数,

    my <- function(df, var){
       a <- sym(paste0(quo_name(enquo(var)), "_x"))
       b <- sym(paste0(quo_name(enquo(var)), "_y"))
    
       df %>% 
          filter(!!a == !!b)
    }
    
    my(test, a)
    my(test, b)
    

    注意:上面的参数包含引用和未引用的参数

    identical(my(test, "a"), my(test, a))
    #[1] TRUE
    identical(my(test, "b"), my(test, b))
    #[1] TRUE
    

    【讨论】:

    • 谢谢阿克伦。它有效!!,正如您在输出中所展示的那样。
    • "sym" 是我缺少的部分。
    • @oscar1mn 第二个函数应该同时使用带引号和不带引号的
    猜你喜欢
    • 1970-01-01
    • 2021-09-27
    • 2020-05-24
    • 2021-02-25
    • 2018-02-21
    • 1970-01-01
    • 1970-01-01
    • 2019-09-26
    • 2013-11-30
    相关资源
    最近更新 更多