Hong Ooi - 5 months ago 25
R Question

# Formula from list of quoted terms

Say I have a list of quoted terms:

``````l <- list(quote(x), quote(y), quote(I(z + 10)))
``````

and I want to turn this into a (one-sided) formula:

``````~ x + y + I(z + 10)
``````

The simplest way to do this would be to turn everything into text and build the formula from scratch, ie, deparse/reparse:

``````formula(paste("~", paste(l, collapse="+")))
``````

which, behind the scenes, is equivalent to

``````formula(paste("~", paste(sapply(l, deparse), collapse="+")))
``````

But that seems a bit inelegant, and possibly prone to parsing screwups. Is there a way to obtain the formula with pure language manipulation?

It's possible to do this in a purely symbolic manner by building up the formula RHS term by term.

``````l <- list(quote(x), quote(y), quote(I(z + 10)))
out <- l[[1]]
for(i in seq_along(l)[-1])
{
out <- substitute(a + b, list(a=out, b=l[[i]]))
}
out <- call("~", out)
out
# ~x + y + I(z + 10)
``````

Note that `out` looks like a formula, but is actually of class (and mode) `call`. To turn it into an actual formula, use `as.formula`:

``````f <- as.formula(out)
``````

However, it can sometimes be advantageous to leave the output as a call object. In particular, if the number of terms is very large, creating the formula can cause a stack overflow:

``````X <- paste0("x", 1:1e5)
X <- lapply(X, as.name)

out <- X[[1]]
for(i in seq_along(X)[-1])
{
out <- substitute(a + b, list(a=out, b=X[[i]]))
}

# this still works
out <- call("~", out)

f <- as.formula(out)
# Error: protect(): protection stack overflow
``````
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download