[R] parse/eval and character encoded expressions: How to deal with non-encoding strings?

William Dunlap wdunlap at tibco.com
Mon Jan 28 17:14:03 CET 2013


Instead of saving a string that can be parsed into a language object (and
later evaluated), I would just save something that that could be evaluated
directly.  Note that a literal like "MyFile" or 3.14 evaluates to itself so you
can save a literal string or a language object and use eval() on either.  Unless
you do this there is no good way to know if "TestDir/TestFile*.txt" means to
do some multiplication and division or to use a glob pattern to find a group of files.
E.g.,

  makeFoo <- function(file, ...) {
      structure(c(...), fileExpr=substitute(file), class="Foo")
  }
  getFileFoo <- function(FooObject) {
      eval(attr(FooObject, "fileExpr"))
  }

used as

  > z <- makeFoo(system.file(package="fpp", "DESCRIPTION"), 1, 2, 3)
  > z
  [1] 1 2 3
  attr(,"fileExpr")
  system.file(package = "fpp", "DESCRIPTION")
  attr(,"class")
  [1] "Foo"
  > getFileFoo(z)
  [1] "C:/Program Files/R/R-2.15.2/library/fpp/DESCRIPTION"
or
  > z <- makeFoo("C:/Temp/File.txt", 1, 2, 3)
  > z
  [1] 1 2 3
  attr(,"fileExpr")
  [1] "C:/Temp/File.txt"
  attr(,"class")
  [1] "Foo"
  > getFileFoo(z)
  [1] "C:/Temp/File.txt"

One thing you might worry about is in which environment the language object is
evaluated (the envir= argument to eval()).  If you embed your object in a formula
then environment(formula) tells you where to evaluate it.  If the formula syntax
is distracting then you can attach an attribribute called ".Environment" to your object
that environment(object) will retrieve.  E.g.,

    makeFooEnv <- function(file, ..., envir = parent.frame()) {
         fileExpr <- structure(substitute(file), .Environment = envir)
         structure(c(...), fileExpr = fileExpr, class="Foo")
    }
    getFileFoo <- function(FooObject) {
         fileExpr <- attr(FooObject, "fileExpr")
         eval(fileExpr, envir=environment(fileExpr))
    }

used as
  > fooObjs <- lapply(1:3, function(i)makeFooEnv(paste0("File",i,".txt"), i^2))
  > fooObjs[[2]]
  [1] 4
  attr(,"fileExpr")
  paste0("File", i, ".txt")
  attr(,"fileExpr")attr(,".Environment")
  <environment: 0x000000000b7f8998>
  attr(,"class")
  [1] "Foo"
  > 
  > i <- 17
  > getFileFoo(fooObjs[[2]]) # Note that eval gets value of i as 2, not 17
  [1] "File2.txt"

Bill Dunlap
Spotfire, TIBCO Software
wdunlap tibco.com

> -----Original Message-----
> From: r-help-bounces at r-project.org [mailto:r-help-bounces at r-project.org] On Behalf
> Of Johannes Graumann
> Sent: Sunday, January 27, 2013 11:29 PM
> To: r-help at stat.math.ethz.ch
> Subject: [R] parse/eval and character encoded expressions: How to deal with non-
> encoding strings?
> 
> Hi,
> 
> I am intending to save a path-describing character object in a slot of a
> class I'm working on. In order to have the option to use "system.file" etc
> in such string-saved path definitions, I wrote this
> 
> ExpressionEvaluator <- function(x){
>   x <- tryCatch(
>     expr=base::parse(text=x),
>     error = function(e){return(as.expression(x))},
>     finally=TRUE)
>   return(x)
> }
> 
> This produces
> 
> > ExpressionEvaluator("system.file(\"INDEX\")")
> expression(system.file("INDEX"))
> > eval(ExpressionEvaluator("system.file(\"INDEX\")"))
> [1] "/usr/lib/R/library/base/INDEX"
> 
> Which is what I want. However,
> 
> > eval(ExpressionEvaluator("Test"))
> Error in eval(expr, envir, enclos) : object 'Test' not found
> 
> prevents me from general usage (also in cases where "x" does NOT encode an
> expression).
> 
> I don't understand why it is that
> > base::parse(text="Test")
> will return
> [1] expression(Test)
> while
> > as.expression("Test")
> produces
> [1] expression("Test")
> which would work with the eval call.
> 
> Can anyone point out to me how to solve this generally? How can I feed the
> function a character object and get back an eval-able expression independent
> of whether there was an expression "encoded" in the input or not.
> 
> Thank you for any hints.
> 
> Sincerely, Joh
> 
> ______________________________________________
> R-help at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
> and provide commented, minimal, self-contained, reproducible code.



More information about the R-help mailing list