整洁的评估无法在 R 中的函数中工作

zhi*_* li 3 r dplyr tidyeval rlang

语境

我正在这个网站上学习整洁评估,我看到一个例子:

x <- sym("height")

expr(transmute(starwars, bmi = mass / (!! x)^2))
#> transmute(starwars, bmi = mass/(height)^2)

transmute(starwars, bmi = mass / (!! x)^2)
#> # A tibble: 87 x 1
#>     bmi
#>   <dbl>
#> 1  26.0
#> 2  26.9
#> 3  34.7
#> 4  33.3
#> # ... with 83 more rows
Run Code Online (Sandbox Code Playgroud)

sym然后,我在自己的代码中使用and模仿了上面的例子!!,但是报错了。

library(survival)
library(rms)
data(cancer)

x = sym('meal.cal')

expr(cph(Surv(time, status) ~ rcs(!! x), data = lung))
# cph(Surv(time, status) ~ rcs(meal.cal), data = lung)

cph(Surv(time, status) ~ rcs(!!x), data = lung)
# Error in !x : invalid argument type

Run Code Online (Sandbox Code Playgroud)

问题

为什么我在我的代码中使用symand!!会报错以及如何修复它。

难道是因为rcs().

Tim*_*Fan 8

我们可以使用rlang::inject()将参数拼接到!!通常不支持整洁评估的函数中。这使我们免于使用eval(expr(...)),也回答了您为什么我们不需要使用 的rlang::inject()问题dplyr::transmute()。后者已经支持整洁的评估,但cph()不支持。

library(survival)
library(rms)
data(cancer)

x = sym('meal.cal')

rlang::inject(cph(Surv(time, status) ~ rcs(!!x), data = lung))
#> Frequencies of Missing Values Due to Each Variable
#> Surv(time, status)           meal.cal 
#>                  0                 47 
#> 
#> Cox Proportional Hazards Model
#>  
#>  cph(formula = Surv(time, status) ~ rcs(meal.cal), data = lung)
#>  
#>  
#>                          Model Tests    Discrimination    
#>                                                Indexes    
#>  Obs        181    LR chi2      0.72    R2       0.004    
#>  Events     134    d.f.            4    R2(4,181)0.000    
#>  Center -0.3714    Pr(> chi2) 0.9485    R2(4,134)0.000    
#>                    Score chi2   0.76    Dxy      0.048    
#>                    Pr(> chi2) 0.9443                      
#>  
#>              Coef    S.E.   Wald Z Pr(>|Z|)
#>  meal.cal    -0.0006 0.0013 -0.48  0.6299  
#>  meal.cal'    0.0007 0.0051  0.14  0.8860  
#>  meal.cal''   0.0010 0.0261  0.04  0.9682  
#>  meal.cal''' -0.0132 0.0676 -0.19  0.8456  
#> 
Run Code Online (Sandbox Code Playgroud)

如果没有整洁的评估,我们可以留在基础 R 中并使用eval(bquote(...))x拼接.(x)

library(survival)
library(rms)
data(cancer)

x = sym('meal.cal')

eval(bquote(cph(Surv(time, status) ~ rcs(.(x)), data = lung)))
#> Frequencies of Missing Values Due to Each Variable
#> Surv(time, status)           meal.cal 
#>                  0                 47 
#> 
#> Cox Proportional Hazards Model
#>  
#>  cph(formula = Surv(time, status) ~ rcs(meal.cal), data = lung)
#>  
#>  
#>                          Model Tests    Discrimination    
#>                                                Indexes    
#>  Obs        181    LR chi2      0.72    R2       0.004    
#>  Events     134    d.f.            4    R2(4,181)0.000    
#>  Center -0.3714    Pr(> chi2) 0.9485    R2(4,134)0.000    
#>                    Score chi2   0.76    Dxy      0.048    
#>                    Pr(> chi2) 0.9443                      
#>  
#>              Coef    S.E.   Wald Z Pr(>|Z|)
#>  meal.cal    -0.0006 0.0013 -0.48  0.6299  
#>  meal.cal'    0.0007 0.0051  0.14  0.8860  
#>  meal.cal''   0.0010 0.0261  0.04  0.9682  
#>  meal.cal''' -0.0132 0.0676 -0.19  0.8456  
#> 
Run Code Online (Sandbox Code Playgroud)

由reprex 包(v2.0.1)于 2022-09-26 创建