Home > Back-end >  tidy evaluation cannot work in function in R
tidy evaluation cannot work in function in R

Time:09-26

Context

I am learning tidy evaluation on this website, And I see an example:

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

Then, I imitated the above example in my own code using sym and !!, but it reported an error.

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

Question

Why do I use sym and !! in my code will report an error and how to fix it.

Is it because of the rcs().

CodePudding user response:

You can use eval()

eval(expr(cph(Surv(time, status) ~ rcs(!! x), data = lung)))

CodePudding user response:

We can use rlang::inject() to splice arguments with !! into functions that usually don't support tidy evaluation. This saves us from using eval(expr(...)) and also answers your question why we don't need rlang::inject() with dplyr::transmute(). The latter already supports tidy evaluation while cph() does not.

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  
#> 

Without tidy evaluation we can stay in base R and use eval(bquote(...)) and splice x with .(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  
#> 

Created on 2022-09-26 by the reprex package (v2.0.1)

  • Related