Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

tidy evaluation cannot work in function in R

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().

like image 576
zhiwei li Avatar asked Mar 30 '26 04:03

zhiwei li


1 Answers

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)

like image 116
TimTeaFan Avatar answered Apr 02 '26 13:04

TimTeaFan



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!