[R] parse/eval and character encoded expressions: How to deal with non-encoding strings?
William Dunlap
wdunlap at tibco.com
Mon Jan 28 17:40:15 CET 2013
I said
> you can attach an attribribute called ".Environment" to your object
> that environment(object) will retrieve
You can also use
environment(object) <- envir
instead of
object <- structure(object, .Environment = envir)
to set the ".Environment" attribute to envir. This makes the code more
symmetric and you don't have remember the magic attribute name.
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 William Dunlap
> Sent: Monday, January 28, 2013 8:14 AM
> To: Johannes Graumann; r-help at stat.math.ethz.ch
> Subject: Re: [R] parse/eval and character encoded expressions: How to deal with non-
> encoding strings?
>
> 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.
>
> ______________________________________________
> 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