以编程方式将dplyr :: case_when与参数一起使用 [英] Use dplyr::case_when with arguments programmatically
问题描述
我希望能够以编程方式使用 dplyr
的 case_when
替换基数R cut()
函数。
I'd like to be able to use dplyr
's case_when
in a programmatic way to replace base R cut()
function.
当前,case_when可以通过NSE与外部参数一起使用,例如:
Currently, case_when can be used with an external argument through NSE like :
library(dplyr)
library(rlang)
patterns <- list(
x <= 2 ~ "<=2",
x <= 4 ~ "2<->4",
x > 4 ~ ">4"
)
x <- 1:10
case_when(!!!patterns)
什么我想做的是:在mutate中与另一个变量一起使用
What I want to do is : use it with another variable, inside a mutate
想法是这样的,尽管我不知道该怎么去工作:
The idea would be something like this, although I can't figure out how to get it to work :
library(dplyr)
patterns_lazy <- list(
!!quo(x) <= 2 ~ "<=2",
!!quo(x) <= 4 ~ "2<->4",
!!quo(x) > 4 ~ ">4"
)
x <- "cyl"
mtcars %>% mutate(ABC = case_when(!!!patterns_lazy))
我会喜欢e能够定义要过滤的列(在字符串内),并检索类似的内容(此示例由于所需的语法而无法正常工作):
I'd like to be able to define the column (inside a string) that I want to filter on, and retrieve something like this (this example is not working as it's the desired syntax):
x <- "cyl"
mtcars %>%
select(cyl) %>%
mutate(ABC = case_when(!!!patterns_lazy)) %>%
head()
cyl ABC
1 6 >4
2 6 >4
3 4 2<->4
4 6 >4
5 8 >4
6 6 >4
感谢您的帮助:)
推荐答案
您不能使用 !!
那里:
patterns <- list(
!!quo(x) <= 2 ~ "<=2",
!!quo(x) <= 4 ~ "2<->4",
!!quo(x) > 4 ~ ">4"
)
- 都不code> list()或
〜
不支持准引用。 - 如果确实支持准引用,您需要注意运算符的优先级,并将
!! quo()
括在括号中。 - 最后,引用到
x
会得出一个字符串,并且您将数字与字符串进行比较(在您的示例中为cyl
)借助隐式强制,R会很高兴:/
- Neither
list()
nor~
support quasiquotation. - If it did support quasiquotation, you'd need to be careful with operator precedence and wrap your
!!quo()
in parentheses. - And finally, that quote to
x
would evaluate to a string and you'd be comparing numbers with strings (in your example it would be"cyl
) which R will do happily thanks to implicit coercions :/
所以您需要使用 exprs()
而不是 list()
,并使用 x
和
.data
代词,而不是 x
的报价。
So you need to use exprs()
instead of list()
, and use x
with the
.data
pronoun instead of a quote of x
.
exprs()
将创建未评估表达式的列表。未评估的
很好:如果对公式进行了评估,它将带有
的环境(此处为全局env),并且该环境不包含任何提供给dplyr的
数据,并且特别是没有 .data
代词。另一方面,如果公式是无上下文的,则它们
将在我们想要的数据上下文中求值。
exprs()
will create a list of unevaluated expressions. Unevaluated
is good: if your formula was evaluated, it would carry an environment
(here the global env) and that environment doesn't contain any of the
data supplied to dplyr, and in particular doesn't have the .data
pronoun. On the other hand if the formulas are "context-less", they
get evaluated in the data context which is what we want.
patterns_lazy <- exprs(
.data[[x]] <= 2 ~ "<=2",
.data[[x]] <= 4 ~ "2<->4",
.data[[x]] > 4 ~ ">4"
)
x <- "cyl"
pull(mutate(mtcars, case_when(!!!patterns_lazy)))
#> [1] ">4" ">4" "2<->4" ">4" ">4" ">4" ">4" "2<->4" "2<->4"
#> [10] ">4" ">4" ">4" ">4" ">4" ">4" ">4" ">4" "2<->4"
#> [19] "2<->4" "2<->4" "2<->4" ">4" ">4" ">4" ">4" "2<->4" "2<->4"
#> [28] "2<->4" ">4" ">4" ">4" "2<->4"
这篇关于以编程方式将dplyr :: case_when与参数一起使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!