来自 rlang 包的 inject() 函数不能与 R 中 rms 包中的 Predict() 函数一起使用



>上下文

我正在学习使用整洁的评估来编写自己的函数。

如果我在不使用整洁的 eval 的情况下计算hr1,代码工作正常,例如:

hr1 = Predict(fit, meal.cal = q, fun = exp, ref.zero = TRUE)

当我结合使用rlang::inject()rms::Predict()来计算hr1时,会发生错误,例如:

hr1= rlang::inject(Predict(fit, !!x = q, fun = exp, ref.zero = TRUE))

问题

如何正确使用rlang::object()rms::Predict()

可重现的代码

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 ="

命名参数的左侧(即=在调用中)必须是名称,不能是表达式。要解决此限制,您可以在此处使用拼接:

hr1 = rlang::inject(Predict(fit, !!! setNames(list(q), "foo"), fun = exp, ref.zero = TRUE))

通常,"rlang"允许:=代替命名参数的=来解决R语法限制,但由于某种原因inject不支持这一点。

正如 Henry @Lionel在评论中指出的那样,另一种解决方法是使用常规do.call,我们需要以列表形式提供参数,并将其与允许在左侧使用:=和拼接的rlang::list2()一起使用:

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

创建于 2022-09-28 由 reprex 软件包 (v2.0.1)

最新更新