Skip to content

formula argument evaluation

8 messages · Adrian Dusa, Duncan Murdoch, Keith Jewell +2 more

#
I have a simple function such as:

foo <- function(x) {
    call <- lapply(match.call(), deparse)
    testit <- capture.output(tryCatch(eval(x), error = function(e) e))
    if (grepl("Error", testit)) {
        return(call$x)
    }
}

and I would like to detect a formula when x is not an object:

# this works
[1] "A + B"

# but this doesn't
Error: unexpected '=' in "foo(A + B ="

Can I prevent it from evaluating the "=" sign?
The addition sign "+" hasn't been evaluated, and I was hoping the "=" would
not get evaluated either. The "=>" sign is important for other purposes,
not related to this example.

Thank you in advance,
Adrian

--
Adrian Dusa
University of Bucharest
Romanian Social Data Archive
Soseaua Panduri nr.90
050663 Bucharest sector 5
Romania
#
On 12/04/2016 6:24 AM, Adrian Du?a wrote:
It never gets to evaluating it.  It is not a legal R statement, so the 
parser signals an error.

If you want to pass arbitrary strings to a function, you need to put 
them in quotes.

Duncan Murdoch
#
On 12/04/2016 11:24, Adrian Du?a wrote:
Did you mean
 > foo (A + B >= C)
??
#
On Tue, Apr 12, 2016 at 2:08 PM, Duncan Murdoch <murdoch.duncan at gmail.com>
wrote:
parser signals an error.
in quotes.

I see. I thought it was parsed inside the function, but if it's parsed
before then quoting is the only option.


To Keith: no, I mean it like this "A + B => C" which is translated as:
"the union of A and B is sufficient for C" in set theoretic language.

The "=>" operator means sufficiency, while "<=" means necessity. Quoting
the expression is good enough, I was just curious if the quotes could be
made redundant, somehow.

Thank you both,
Adrian

--
Adrian Dusa
University of Bucharest
Romanian Social Data Archive
Soseaua Panduri nr.90
050663 Bucharest sector 5
Romania
#
Would making it regular function %=>%, using "%" instead of quotes,
work for you?
On Tue, Apr 12, 2016 at 11:09 AM, Adrian Du?a <dusa.adrian at unibuc.ro> wrote:
#
I suppose it would work, although "=>" is rather a descriptive symbol and
less a function.
But choosing between quoting:
"A + B => C"
and a regular function:
A + B %=>% C
probably quoting is the most straightforward, as the result of the foo()
function has to be a string anyways (which is parsed by other functions).

On Tue, Apr 12, 2016 at 6:20 PM, Richard M. Heiberger <rmh at temple.edu>
wrote:

  
    
#
%=>% would have precendence ('order of operations') problems also.

   A + B %=>% C

is equivalent to

  A + ( B %=>% C)

and I don't think that is what you want.

as.list(quote(A + B %=>% C)) shows the first branch in the parse tree.  The
following function, str.language, shows the entire parse tree, as in

  > str.language(quote(A + B %=>% C))
  `quote(A + B %=>% C)` call(3): A + B %=>% C
    `` name(1): +
    `` name(1): A
    `` call(3): B %=>% C
      `` name(1): %=>%
      `` name(1): B
      `` name(1): C

str.language <-
function (object, ..., level = 0, name = myDeparse(substitute(object)))
{
    abbr <- function(string, maxlen = 25) {
        if (length(string) > 1 || nchar(string) > maxlen)
            paste(substring(string[1], 1, maxlen), "...", sep = "")
        else string
    }
    myDeparse <- function(object) {
        if (!is.environment(object)) {
            deparse(object)
        }
        else {
            ename <- environmentName(object)
            if (ename == "")
                ename <- "<unnamed env>"
            paste(sep = "", "<", ename, "> ", paste(collapse = " ",
                objects(object)))
        }
    }
    cat(rep("  ", level), sep = "")
    if (is.null(name))
        name <- ""
    cat(sprintf("`%s` %s(%d): %s\n", abbr(name), class(object),
        length(object), abbr(myDeparse(object))))
    a <- attributes(object)
    if (is.recursive(object) && !is.environment(object)) {
        object <- as.list(object)
        names <- names(object)
        for (i in seq_along(object)) {
            str.language(object[[i]], ..., level = level + 1,
                name = names[i])
        }
    }
    a$names <- NULL
    if (length(a) > 0) {
        str.language(a, level = level + 1, name = paste("Attributes of",
            abbr(name)))
    }
}



Bill Dunlap
TIBCO Software
wdunlap tibco.com
On Tue, Apr 12, 2016 at 11:59 PM, Adrian Du?a <dusa.adrian at unibuc.ro> wrote:

            

  
  
1 day later
#
Thanks Bill, it's very useful to know how parsing and evaluation works.
It seems that quoting is the least complicated solution which is guaranteed
to work.

Best,
Adrian
On 13 Apr 2016 6:04 p.m., "William Dunlap" <wdunlap at tibco.com> wrote: