Using tidy selection together with the survival package - "Error: promise already under evaluation"
Using tidy selection together with the survival package - "Error: promise already under evaluation"
我正在编写一个 R 函数,允许用户在创建 survival::survfit
对象时指定一个单独的时间变量。 survival
包具有“无字符串”语法,这意味着时间变量的名称(在我的例子中为“dtime”)不需要任何引号:
survival::survfit(formula = survival::Surv(dtime, death) ~ 1, rotterdam)
因此,我想我可以使用 tidy evaluation 来达到我的目的。这是我的代码:
# My function
get_survfit <- function(.data, .time){
return(survival::survfit(formula = survival::Surv({{ .time }}, status) ~ 1, .data))
}
# Application example
library(survival)
data(cancer)
rotterdam
colnames(rotterdam)[which(names(rotterdam) == "death")] = "status"
get_survfit(.data=rotterdam, .time=dtime)
但是,我总是遇到以下错误:
Error in in survival::Surv({ : object 'dtime' not found
在调试器中查看 'dtime' 时,我得到:
Error during wrapup :
promise already under evaluation: recursive default argument reference or earlier
problems?
如何解决此问题并仍然获得我的功能?
survfit()
不是一个整洁的 eval 函数,因此您在断章取意地使用 {{
。参见 https://rlang.r-lib.org/reference/topic-inject-out-of-context.html。
相反,您需要使用 inject()
来启用从外部注入。由于 survfit()
不是整洁的 eval 函数,因此它不支持 {{
创建的 quosures。所以你需要使用 !!
和 ensym()
.
get_survfit <- function(data, time) {
time <- ensym(time)
inject(
survival::survfit(formula = survival::Surv(!!time, status) ~ 1, data)
)
}
ensym()
确保传递简单的变量名,并消除它们。 !!
在公式中注入变量。
基于 Lionel Henry 的回答并受到 的启发,我想补充一点,使用 enquo
和 get_expr
也可以达到相同的结果:
get_survfit <- function(.data, .time){
.time = rlang::enquo(.time)
.time = rlang::get_expr(.time)
rlang::inject(
return(survival::survfit(formula = survival::Surv(!!.time, status) ~ 1, .data))
)
}
我正在编写一个 R 函数,允许用户在创建 survival::survfit
对象时指定一个单独的时间变量。 survival
包具有“无字符串”语法,这意味着时间变量的名称(在我的例子中为“dtime”)不需要任何引号:
survival::survfit(formula = survival::Surv(dtime, death) ~ 1, rotterdam)
因此,我想我可以使用 tidy evaluation 来达到我的目的。这是我的代码:
# My function
get_survfit <- function(.data, .time){
return(survival::survfit(formula = survival::Surv({{ .time }}, status) ~ 1, .data))
}
# Application example
library(survival)
data(cancer)
rotterdam
colnames(rotterdam)[which(names(rotterdam) == "death")] = "status"
get_survfit(.data=rotterdam, .time=dtime)
但是,我总是遇到以下错误:
Error in in survival::Surv({ : object 'dtime' not found
在调试器中查看 'dtime' 时,我得到:
Error during wrapup : promise already under evaluation: recursive default argument reference or earlier problems?
如何解决此问题并仍然获得我的功能?
survfit()
不是一个整洁的 eval 函数,因此您在断章取意地使用 {{
。参见 https://rlang.r-lib.org/reference/topic-inject-out-of-context.html。
相反,您需要使用 inject()
来启用从外部注入。由于 survfit()
不是整洁的 eval 函数,因此它不支持 {{
创建的 quosures。所以你需要使用 !!
和 ensym()
.
get_survfit <- function(data, time) {
time <- ensym(time)
inject(
survival::survfit(formula = survival::Surv(!!time, status) ~ 1, data)
)
}
ensym()
确保传递简单的变量名,并消除它们。 !!
在公式中注入变量。
基于 Lionel Henry 的回答并受到 enquo
和 get_expr
也可以达到相同的结果:
get_survfit <- function(.data, .time){
.time = rlang::enquo(.time)
.time = rlang::get_expr(.time)
rlang::inject(
return(survival::survfit(formula = survival::Surv(!!.time, status) ~ 1, .data))
)
}