【问题标题】:Programming logical operations as arguments using tidyverse使用 tidyverse 将逻辑运算编程为参数
【发布时间】:2020-05-17 09:13:50
【问题描述】:

如何为 R 中的函数提供逻辑参数,使用 tidyverse 函数进行编程? This related question 不允许用户更改逻辑运算符,它假定函数的用户总是想要==

请参见下面的代码示例和迄今为止的尝试。

# example data
library(tidyverse)
dat <- tibble(x = letters[1:4], y = 1:4, z = 5:8)

# what I want to do is have a function that passes arguments to filter()
# so that I can flexibly subset data:
dat %>% 
  filter(x == "a" | y < 2)

dat %>% 
  filter(x == "b" & y < 1)

dat %>% 
  filter(y == max(y))

# what would I pass to lgl to do this in a function?
# I want to be a ble to feed in different logical expressions, notalways using
#    the same variables and operations, like the documentation for filter()
#    demonstrates

# tries so far:
fun <- function(dat, lgl) filter(dat, lgl)
fun(dat, x == "a" | y < 2)

fun <- function(dat, lgl) filter(dat, quo(lgl))
fun(dat, x == "a" | y < 2)

fun <- function(dat, lgl) filter(dat, quos(lgl))
fun(dat, x == "a" | y < 2)

fun <- function(dat, lgl) filter(dat, !!sym(lgl))
fun(dat, 'x == "a" | y < 2')

fun <- function(dat, lgl) filter(dat, !!!syms(lgl))
fun(dat, 'x == "a" | y < 2')

fun <- function(dat, lgl) filter(dat, expr(lgl))
fun(dat, x == "a" | y < 2)

fun <- function(dat, lgl) filter(dat, eval(lgl, envir = parent.frame()))
fun(dat, x == "a" | y < 2)

【问题讨论】:

  • 为什么不使用filter(dat, x == "a" | y &lt;2)?您是否可以描述另一个不允许这样做的用例?
  • 这只是一个最低限度的可重现示例。该函数本身会进行大量的数据整理和汇总。不过,过滤器位是我唯一被挂断的地方。而且我想要一个函数,而不是复制粘贴代码节的次数过多。
  • 好吧,在这种情况下,我不知道有任何方法可以适当地传递列名(除了下面的解决方案),但你可以这样做fun &lt;- function(dat, lgl, ...) filter(dat, eval(lgl)); fun(dat, expression(x = 5 | y &lt;2))。我不建议将表达式作为字符串传递,如果只是因为解析相当混乱,所以你必须使用 xor 而不是 | 之类的东西,我从来没有想出如何适当地转义。跨度>

标签: r dplyr tidyverse tidyeval


【解决方案1】:

在编写示例时,我找到了解决方案。但我想我会在这里发帖,以防万一有人遇到类似问题:

> fun <- function(dat, ...) filter(dat, ...)
> fun(dat, x == "a" | y < 2)
# A tibble: 1 x 3
  x         y     z
  <chr> <int> <int>
1 a         1     5

不过,这在某种程度上是一种解决方法,因为它实际上并不解释表达式,而只是传递参数。看到另一种解决方案也会很有趣。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-02-25
    • 1970-01-01
    • 2016-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-14
    • 2020-02-02
    相关资源
    最近更新 更多