Context
I am learning use tidy eval to write my own function.
If I calculate hr1
without using tidy eval, the code works fine, such as:
hr1 = Predict(fit, meal.cal = q, fun = exp, ref.zero = TRUE)
When I use rlang::inject()
and rms::Predict()
jointly to calculate hr1
, an error occurs, such as:
hr1= rlang::inject(Predict(fit, !!x = q, fun = exp, ref.zero = TRUE))
Question
How to use rlang::object()
and rms::Predict()
correctly jointly?
Reproducible code
library(survival)
library(rms)
data(cancer)
x = sym('meal.cal')
q = quantile(lung[[x]], probs = c(0.05, 0.35, 0.65, 0.95), na.rm = T)
fit = rlang::inject(cph(Surv(time, status) ~ rcs(!!x), data = lung))
dd = datadist(lung)
options(datadist = 'dd') # Predict() cannot work without set the options
hr1 = Predict(fit, meal.cal = q, fun = exp, ref.zero = TRUE) # Run successful
head(hr1)
# meal.cal yhat lower upper
# 1 338 1.2486497 0.7310498 2.132722
# 2 825 0.9916446 0.7766063 1.266226
# 3 1039 1.0245228 0.8826652 1.189179
# 4 1425 1.0558754 0.6322319 1.763392
#
# Response variable (y):
#
# Limits are 0.95 confidence limits
hr1= rlang::inject(Predict(fit, !!x = q, fun = exp, ref.zero = TRUE)) # Run failed
# Error: unexpected '=' in "hr1= rlang::inject(Predict(fit, !!x ="
CodePudding user response:
The left-hand side of a named parameter (i.e. =
inside a call) must be a name, it cannot be an expression. To work around this limitation, you can use splicing here:
hr1 = rlang::inject(Predict(fit, !!! setNames(list(q), "foo"), fun = exp, ref.zero = TRUE))
In general, ‘rlang’ allows :=
in the place of =
for named arguments to work around the R syntax limitation but for some reason inject
does not support this.
CodePudding user response:
As @Lionel Henry notes in the comments, another workaround is to use a regular do.call
where we need to supply the arguments in list form and we use that together with rlang::list2()
which allows the use of :=
and splicing on the lefthand side:
library(survival)
library(rms)
data(cancer)
do.call(Predict, rlang::list2(fit, !! x := q, fun = exp, ref.zero = TRUE))
#> meal.cal yhat lower upper
#> 1 338 1.2486497 0.7310498 2.132722
#> 2 825 0.9916446 0.7766063 1.266226
#> 3 1039 1.0245228 0.8826652 1.189179
#> 4 1425 1.0558754 0.6322319 1.763392
#>
#> Response variable (y):
#>
#> Limits are 0.95 confidence limits
Created on 2022-09-28 by the reprex package (v2.0.1)