r - 使用 dplyr 在自定义函数中无法识别默认参数
问题描述
拿这个功能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)
我确信我对 quasiquotation 的了解存在一些差距,但我想了解如何在foo()
.
解决方案
这是一个可以“工作”的,虽然我不推荐它
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
变量。
最好在直接传入输入数据的地方创建适当的函数(而不是他们需要自己查找的变量名)。
推荐阅读
- excel - 在电源查询中创建循环以创建新列
- python - Python中的IF / ELSE控制流从4种选择中计算出快递服务的价格
- node.js - 错误:在 Request.callback 未经授权。状态:401
- variables - Application.cfc 中客户端范围变量中的字符串连接函数的问题
- reactjs - 如何使用 textInput 从下一个屏幕获取数据到上一个屏幕,该屏幕仅在反应原生中使用 Text 字段
- python - 如何找到旋转角度,所以两点的Y轴相同
- google-api - 将 YouTube 数据 API 的配额增加到 1000 万或 5000 万单位,谷歌收取多少费用
- android - 绑定服务失败
- python - 将季度数据框转换为月度数据并填充 Pandas 中的缺失值
- oracle - 如何在perl中检查先前执行的命令的状态