Reputation: 513
I am writing an R function that allows the user to specify an individual time variable when creating a survival::survfit
object. The survival
package has a "string-free" syntax, which means that the name of the time variable (in my case "dtime") does not need any quotation marks:
survival::survfit(formula = survival::Surv(dtime, death) ~ 1, rotterdam)
Hence, I figured that I could use tidy evaluation for my purpose. Here is my code:
# 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)
However, I always get the following errors:
Error in in survival::Surv({ : object 'dtime' not found
and when looking into 'dtime' in the debugger, I get:
Error during wrapup : promise already under evaluation: recursive default argument reference or earlier problems?
How can I fix this and still obtain my feature?
Upvotes: 1
Views: 112
Reputation: 513
Building on Lionel Henry's answer and inspired by another question I asked, I would like to add that it is also possible to achieve the same result with enquo
and 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))
)
}
Upvotes: 0
Reputation: 6803
survfit()
is not a tidy eval function so you're using {{
out of context. See https://rlang.r-lib.org/reference/topic-inject-out-of-context.html.
Instead you'll need to use inject()
to enable injection from the outside. Since survfit()
is not a tidy eval function it won't support quosures, which {{
creates. So you'll need to use !!
instead, together with ensym()
.
get_survfit <- function(data, time) {
time <- ensym(time)
inject(
survival::survfit(formula = survival::Surv(!!time, status) ~ 1, data)
)
}
ensym()
ensures that simple variable names are passed, and defuses them. !!
injects the variable in the formula.
Upvotes: 1