[R] debugging substitute function in R 2.11

Gil Tomás gil.tms at gmail.com
Fri May 14 11:09:05 CEST 2010


Dear list,

A while ago I found in the web a function (sadly I can't credit the
author as I don't remember where I picked it up from) whose output is
a dataframe that lists for every object in the global environment its
class, mode, dim & length (where applicable). It is meant to be an
upgrade to the ls () function with a far more informative and detailed
output and it quickly became one of my most frequent calls in any R
session (source added to my .Rprofile). However, since I upgraded to R
2.11, the function stopped working, retrieving the following error:

******
R> ll ()
Error in substitute({ :
  unused argument(s) (list = list(member = as.name(member), property =
property, fcn = as.name(property)))
******

This seems to be due to a change in the substitute function in R 2.11,
as described in the release notes:

******
Primitive functions UseMethod(), attr(), attr<-(), on.exit(),
	retracemem() and substitute() now use standard argument
	matching (rather than positional matching).  This means that
	all multi-argument primitives which are not internal now use
	standard argument matching except where positional matching is
	desirable (as for switch(), call(), .C() ...).
******

I've tried to debug it myself, but unfortunately my knowledge of R is
not deep enough to find a compatible version of the function with R
2.11 yet. Here is the ll () function:

******
ll <- function() {
  df <- NULL
  envir <- parent.frame ()
  for (member in ls (envir = envir))
    {
      oneRow <- list (member = member)
      for (property in c ("class", "mode", "dim", "length"))
        {
          value <- eval (substitute ( # this is the call producing the
error in R 2.11
                                     {
                                       fcn <- get (property, mode = "function")
                                       fcn (member)
                                     },
                                     list = list (member = as.name (member),
                                       property = property,
                                       fcn = as.name (property))
                                     ),
                         envir = envir)
      if (is.null (value))
        value <- "NULL"
      else if (is.vector (value) && length (value) > 1)
        value <- sprintf ("c(%s)", paste (value, collapse = ","))
      else if (is.list (value))
        value <- unlist (value)
      if (length (value) > 0)
        value <- value[1]
      value <- as.character (value)
          oneRow[[property]] <- value
        }
      df <- rbind (df, as.data.frame (oneRow))
    }
  df
}
******

Could anyone give me a hint as how to tweak the substitute call to
render it compatible with R 2.11?

Any help greatly appreciated,
Gil



More information about the R-help mailing list