[R] Help on a Display function

Hans W Borchers hwborchers at googlemail.com
Sat Jan 15 15:26:42 CET 2011


William Dunlap <wdunlap <at> tibco.com> writes:
> 
> But it fails on this:
>   > my_names <- c("Bill", "William")
>   > display(rev(my_names))
>   rev(my_names) = Error in cat(list(...), file, sep, fill, labels,
> append) : 
>     argument 3 (type 'list') cannot be handled by 'cat'
> This is because you call eval() using the environment of the
> function, while ordinary argument evaluation evaluates them
> in the environment of the caller.   Do not use eval() directly
> but use the ordinary evaluation that R does automatically. 

I appreciate this extensive answer.
So I decided to use the following function, suppressing the deparsed form
if there is a tag (while I'm inclined to forbid function code as input):

    display <- function (...) {
        evaluatedArgs <- list(...)
        n <- length(evaluatedArgs)
        argTags <- names(evaluatedArgs)
        deparsedArgs <- lapply(substitute(placeholderFunction(...))[-1], 
            function(expr) {
                d <- deparse(expr)
                paste(d, collapse = "\n        ")
            }
        )
        if (is.null(argTags)) argTags <- rep("", n)
        namedArgs <- ifelse(argTags != "", argTags, deparsedArgs)
        cat(paste(namedArgs, evaluatedArgs, sep=" = "), sep = "\n")
    }

It works fine on your examples,

    my_names <- c("Bill", "William")
    display(x=log(10), 1+2+3, sin(1), rev(my_names),
            z=(function(p){lp<-log(p);lp+lp^2/2+lp^3/6})(0.2))
    # x = 2.30258509299405
    # 1 + 2 + 3 = 6
    # sin(1) = 0.841470984807897
    # rev(my_names) = c("William", "Bill")
    # z = -1.00911130949159

while there still are problems with matrices (and probably other structures):

    A <- matrix(1:4, 2, 2); B=diag(4)
    display(A, B)
    # A = 1:4
    # B = c(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1)

I guess I have to define my own output representation in these cases, based
on "lapply(evaluatedArgs, class)".

Many thanks, Hans Werner

>   display2 <- function (...) 
>   {
>       evaluatedArgs <- list(...)
>       argTags <- names(evaluatedArgs)
>       deparsedArgs <- lapply(substitute(placeholderFunction(...))[-1], 
>           function(expr) {
>               d <- deparse(expr)
>               paste(d, collapse = "\n        ") # or d[1] or ...
>         })
>       # use if(is.null(argTags)) ... cat without argTags ... ?
>       cat(paste(sep = " = ", argTags, deparsedArgs, evaluatedArgs), 
>           sep = "\n")
>   }
>   > my_names <- c("Bill", "William")
>   > display2(rev(my_names))
>    = rev(my_names) = c("William", "Bill")
>   > display2(strings=rev(my_names))
>   strings = rev(my_names) = c("William", "Bill")
>   > display2(x=log(10), 1+2+3,
> z=(function(p){lp<-log(p);lp+lp^2/2+lp^3/6})(0.2))
>   x = log(10) = 2.30258509299405
>    = 1 + 2 + 3 = 6
>   z = (function(p) {
>               lp <- log(p)
>               lp + lp^2/2 + lp^3/6
>           })(0.2) = -1.00911130949159
> 
> > 
> > My questions:
> > 
> > (1) Is there a better or more appropriate way to write such a 
> > function? ---
> >     I'm not so well versed in internal R functions such as 
> > (de)parse(),
> >     substitute(), or eval().
> > 
> > (2) What is the role of the "placeholderFunction"? I could 
> > not find enough
> >     information about it resp. about the whole construction.
> 
> The function
>   f <- function(x) substitute(func(x))
> produces an object of class "call" whose first element
> is the name "func" and whose subsequent elements are
> the arguments in the call.  The [-1] strips off the
> function name.  You might also do
>   f <- function(x) substitute((x))
> which produces an object of class "(" whose first element
> is the name "(" which you can strip off.  "(" is easier
> to misread and "(" objects must have length 2, while
> call objects have any length greater than 0.
> 
> I learned about this by playing around with the output of
> quote() (or parse() or substitute() or expression()).  Look
> at the class, length, and [[elements]] of expressions.
> The following str.language might get you started.  It prints
> the name, class, length, and a summary of the value of each
> part of an expression.
> 
> [...]
> 
> Bill Dunlap
> Spotfire, TIBCO Software
> wdunlap tibco.com 
> 
> > 
> > Thanks, Hans Werner
>



More information about the R-help mailing list