Skip to content
Prev 49171 / 63424 Next

Most efficient way to check the length of a variable mentioned in a formula.

I would use eval(), but I think that most formula-using functions do
it more like the following.

getRHSLength <-
function (formula, data = parent.frame())
{
    rhsExpr <- formula[[length(formula)]]
    rhsValue <- eval(rhsExpr, envir = data, enclos = environment(formula))
    length(rhsValue)
}

* use eval() instead of get() so you will find variables are in
ancestral environments
of envir (if envir is an environment), not just envir itself.
* just evaluate the stuff in the formula using the non-standard
evaluation frame,
call length() in the current frame.  Otherwise, if  envir inherits
directly from emptyenv() the 'length' function will not be found.
* use envir=data so it looks first in the data argument for variables
* the enclos argument is used if envir is not an environment and is used to
find variables that are not in envir.

Here are some examples:
  > X <- 1:10
  > getRHSLength(~X)
  [1] 10
  > getRHSLength(~X, data=data.frame(X=1:2))
  [1] 2
  > getRHSLength((function(){X <- 1:4; ~X})(), data=data.frame())
  [1] 4
  > getRHSLength((function(){X <- 1:4; ~X})(), data=data.frame(X=1:2))
  [1] 2
  > getRHSLength((function(){X <- 1:4; ~X})(), data=list2env(data.frame()))
  [1] 10
  > getRHSLength((function(){X <- 1:4; ~X})(), data=emptyenv())
  Error in eval(expr, envir, enclos) : object 'X' not found

I think you will see the same lookups if you try analogous things with lm().
Bill Dunlap
TIBCO Software
wdunlap tibco.com
On Fri, Oct 17, 2014 at 11:04 AM, Joris Meys <jorismeys at gmail.com> wrote: