eval() (and parse() )

Adam Ginensky

January 29, 2019

‘If eval is the answer, you’re probably asking the wrong question’- or is it ?

  1. I still think it is useful.
  2. At least one other person agrees with me, see Rchaeology: Idioms of R Programming Paul E. Johnson (available on the web).
  3. There are times when it can help explain what is going on with the code.
  4. I’ve certainly seen it used in the guts of serious code.

What is eval

x = 3
y = 4
eval(3+4)
## [1] 7
eval(x+y)
## [1] 7
eval(paste0(x,"+",y))
## [1] "3+4"
eval(paste0('x',"+","y"))
## [1] "x+y"
eval(parse(text = paste0('x',"+","y")))
## [1] 7

An example

The idea is -

  1. Create an text expression from many variable pieces using paste or paste0
  2. Use parse(text =) to turn that expression that R can evaluate and
  3. Use eval to evaluate the expression.
g = function(a,b){ans = a+ 2*b
ans}
paste0('z=',y,'*cos(x)' )
## [1] "z=4*cos(x)"
paste0('g(exp(z)*y+',2,'+z,z)')
## [1] "g(exp(z)*y+2+z,z)"

Now we can put it together

eval(parse(text =  paste0('z=',y,'*cos(x)')  ))
eval(parse(text =  paste0('g(exp(z)*y+',2,'+z,z)')  ))
## [1] -9.803655

I’ve used this for when I need to save files with different names based on parameter choices

# for( i in some range){
## do some ML stuff and evaluate the results
## Classify the results as say good bad or indifferent in a variable 'outcome' tod = Sys.Date()
# eval(parse( text = paste0("write.csv(","test on ",tod,"",outcome,".txt",")""))
#}
library(MASS) # my favorite data set Boston
library(randomForest) # running a random forest =
## randomForest 4.6-14
## Type rfNews() to see new features/changes/bug fixes.
data(Boston)
summary(Boston)
##       crim                zn             indus            chas        
##  Min.   : 0.00632   Min.   :  0.00   Min.   : 0.46   Min.   :0.00000  
##  1st Qu.: 0.08204   1st Qu.:  0.00   1st Qu.: 5.19   1st Qu.:0.00000  
##  Median : 0.25651   Median :  0.00   Median : 9.69   Median :0.00000  
##  Mean   : 3.61352   Mean   : 11.36   Mean   :11.14   Mean   :0.06917  
##  3rd Qu.: 3.67708   3rd Qu.: 12.50   3rd Qu.:18.10   3rd Qu.:0.00000  
##  Max.   :88.97620   Max.   :100.00   Max.   :27.74   Max.   :1.00000  
##       nox               rm             age              dis        
##  Min.   :0.3850   Min.   :3.561   Min.   :  2.90   Min.   : 1.130  
##  1st Qu.:0.4490   1st Qu.:5.886   1st Qu.: 45.02   1st Qu.: 2.100  
##  Median :0.5380   Median :6.208   Median : 77.50   Median : 3.207  
##  Mean   :0.5547   Mean   :6.285   Mean   : 68.57   Mean   : 3.795  
##  3rd Qu.:0.6240   3rd Qu.:6.623   3rd Qu.: 94.08   3rd Qu.: 5.188  
##  Max.   :0.8710   Max.   :8.780   Max.   :100.00   Max.   :12.127  
##       rad              tax           ptratio          black       
##  Min.   : 1.000   Min.   :187.0   Min.   :12.60   Min.   :  0.32  
##  1st Qu.: 4.000   1st Qu.:279.0   1st Qu.:17.40   1st Qu.:375.38  
##  Median : 5.000   Median :330.0   Median :19.05   Median :391.44  
##  Mean   : 9.549   Mean   :408.2   Mean   :18.46   Mean   :356.67  
##  3rd Qu.:24.000   3rd Qu.:666.0   3rd Qu.:20.20   3rd Qu.:396.23  
##  Max.   :24.000   Max.   :711.0   Max.   :22.00   Max.   :396.90  
##      lstat            medv      
##  Min.   : 1.73   Min.   : 5.00  
##  1st Qu.: 6.95   1st Qu.:17.02  
##  Median :11.36   Median :21.20  
##  Mean   :12.65   Mean   :22.53  
##  3rd Qu.:16.95   3rd Qu.:25.00  
##  Max.   :37.97   Max.   :50.00
i= 2; j=100
flnm = paste0("bost_mtr_",i,"_ntree_",j,".rds")
 flnm    
## [1] "bost_mtr_2_ntree_100.rds"
for(i in 2:4){ # i runs over number of variables
  for(j in (1:5)){ # j is ntree
      tmp = randomForest(medv~., data = Boston, mtry = i, ntree = j)
      flnm = paste0("bost_mtr_",i,"_ntree_",j,".rds")
    eval(parse( text =  paste0('saveRDS(tmp,file =\' ',flnm,' \' )' ) )) # 
    
    
  }
  
}