-----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"
[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"
[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
will return
[1] expression(Test)
while
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