以编程方式将dplyr :: case_when与参数一起使用 [英] Use dplyr::case_when with arguments programmatically

查看:98
本文介绍了以编程方式将dplyr :: case_when与参数一起使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望能够以编程方式使用 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"
)




  1. 都不code> list()或不支持准引用。

  2. 如果确实支持准引用,您需要注意运算符的优先级,并将 !! quo()括在括号中。

  3. 最后,引用到 x 会得出一个字符串,并且您将数字与字符串进行比较(在您的示例中为 cyl )借助隐式强制,R会很高兴:/

  1. Neither list() nor ~ support quasiquotation.
  2. If it did support quasiquotation, you'd need to be careful with operator precedence and wrap your !!quo() in parentheses.
  3. 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆