[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))

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,

More information about the R-help mailing list