首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在使用dplyr的自定义函数中不能识别默认参数

在使用dplyr的自定义函数中不能识别默认参数
EN

Stack Overflow用户
提问于 2021-09-08 20:09:19
回答 2查看 157关注 0票数 2

接受这个函数foo()。我希望它有一个默认的cyl参数,因为这是它通常要处理的字段的名称。

代码语言:javascript
复制
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)

但我感到惊讶的是,除非我显式地提供默认参数,否则该函数将无法工作。参见下面失败的代码

代码语言:javascript
复制
# 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

似乎只有在有数据参数时才会处理默认参数,如下所示。

代码语言:javascript
复制
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()中使用默认参数。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-09-08 20:31:58

我们可以用missingcur_data_all做这件事

代码语言:javascript
复制
foo <- function(x = cyl){
   if(missing(x)) x <- cur_data_all()[["cyl"]]
   
    case_when(
        x == 6 ~ TRUE,
        x == 8 ~ FALSE,
        x == 4 ~ NA
    )
}

-testing

代码语言:javascript
复制
> 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
票数 2
EN

Stack Overflow用户

发布于 2021-09-08 20:22:51

这里有一个会“起作用”的,尽管我不推荐它

代码语言:javascript
复制
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变量。

最好在直接传入输入数据的地方创建适当的函数(而不是他们自己查找的变量名称)。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69109106

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档