[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