接受这个函数foo()。我希望它有一个默认的cyl参数,因为这是它通常要处理的字段的名称。
library(tidyverse)
foo <- function(x = cyl){
case_when(
x == 6 ~ TRUE,
x == 8 ~ FALSE,
x == 4 ~ NA
)
}
# works:
mtcars %>%
mutate(cyl_refactor = foo(cyl)) %>%
select(cyl, cyl_refactor)但我感到惊讶的是,除非我显式地提供默认参数,否则该函数将无法工作。参见下面失败的代码
# fails:
mtcars %>%
mutate(cyl_refactor = foo()) %>%
select(cyl, cyl_refactor)Error: Problem with `mutate()` column `cyl_refactor`. ℹ `cyl_refactor = foo()`. x object 'cyl' not found
似乎只有在有数据参数时才会处理默认参数,如下所示。
foo2 <- function(data, x = cyl){
data %>%
mutate(cyl_refactor = case_when(
{{x}} == 6 ~ TRUE,
{{x}} == 8 ~ FALSE,
{{x}} == 4 ~ NA
))
}
mtcars %>%
foo2() %>%
select(cyl, cyl_refactor)我确信,我对准引号的知识还存在一些空白,但我想了解如何在foo()中使用默认参数。
发布于 2021-09-08 20:31:58
我们可以用missing和cur_data_all做这件事
foo <- function(x = cyl){
if(missing(x)) x <- cur_data_all()[["cyl"]]
case_when(
x == 6 ~ TRUE,
x == 8 ~ FALSE,
x == 4 ~ NA
)
}-testing
> out1 <- mtcars %>%
+ mutate(cyl_refactor = foo(cyl)) %>%
+ select(cyl, cyl_refactor)
> out2 <- mtcars %>%
+ mutate(cyl_refactor = foo()) %>%
+ select(cyl, cyl_refactor)
>
> identical(out1, out2)
[1] TRUE发布于 2021-09-08 20:22:51
这里有一个会“起作用”的,尽管我不推荐它
foo <- function(x = cyl){
x <- enquo(x)
eval.parent(rlang::quo_squash(rlang::quo(case_when(
!!x == 6 ~ TRUE,
!!x == 8 ~ FALSE,
!!x == 4 ~ NA
))))
}
# Both run without error
mtcars %>%
mutate(cyl_refactor = foo(cyl)) %>%
select(cyl, cyl_refactor)
mtcars %>%
mutate(cyl_refactor = foo()) %>%
select(cyl, cyl_refactor)问题是,为了使case_when工作,您不能只传递列名而不传递数据。为了在本例中“查找”数据,我在调用链上使用了eval.parent()来尝试查找cyl变量。
最好在直接传入输入数据的地方创建适当的函数(而不是他们自己查找的变量名称)。
https://stackoverflow.com/questions/69109106
复制相似问题