我希望能够使用 dplyr
的 case_when
以编程方式替换基础 R cut()
功能。
目前, case_when 可以通过 NSE 与外部参数一起使用,例如:
library(dplyr)
library(rlang)
patterns <- list(
x <= 2 ~ "<=2",
x <= 4 ~ "2<->4",
x > 4 ~ ">4"
)
x <- 1:10
case_when(!!!patterns)
我想要做的是:将它与另一个变量一起使用,在 mutate 中
这个想法是这样的,虽然我不知道如何让它工作:
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))
我希望能够定义要过滤的列(在字符串内),并检索这样的内容(此示例无法正常工作,因为它是所需的语法):
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"
)
list()
也不是 ~
支持准报价。 !!quo()
在括号内。 x
将评估为一个字符串,并且您将比较数字与字符串(在您的示例中为 "cyl
),由于隐式强制转换,R 会很高兴地做到这一点:/所以你需要使用
exprs()
而不是 list()
,并使用 x
与.data
代词而不是引用 x
.exprs()
将创建一个未计算的表达式列表。未评估很好:如果你的公式被评估,它会带有一个环境
(这里是全局环境)并且该环境不包含任何
提供给 dplyr 的数据,特别是没有
.data
代词。另一方面,如果公式是“无上下文的”,它们在我们想要的数据上下文中进行评估。
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"
关于r - 以编程方式使用带参数的 dplyr::case_when,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44822256/