Easiest way to determine if a model formula only has an intercept

1k views Asked by At

In R formula syntax, occasionally a user will specify a very simple model that only has an intercept, e.g.

fit = lm(Response ~ 1, data)

These models allow for simplification relative to more complex models, e.g. lm(Response ~ A + B + A:B, ...) and I would like to have an easy way to detect when the RHS of the equation only contains a 1 and no other terms. Text manipulations seem possible, but are there any other ways to do this using the R formula class or other methods?

2

There are 2 answers

2
Ben Bolker On BEST ANSWER

The answer with terms is probably the canonical answer, but you can also use subsetting to drop the LHS of the formula and test it against ~1:

fit = lm(Response ~ 1, data=data.frame(Response=1:10))
identical(formula(fit)[-2],~1)
  • This assumes a two-sided formula
  • To understand the subsetting, you need to know that a two-sided formula is treated as a binary operation and stored as a parse tree of (~,Response,1): the first element is the operator, the second element is the first argument (the LHS), and the right element is the second argument (the RHS). [-2] drops the second element and makes the formula into a one-sided formula.

@G.Grothendieck offers a slightly less hacky variant (no need to know or understand the internal structure of formula objects) in the comments, using update to overwrite the response variable with 0:

identical(update(formula(fit), 0 ~ .), 0 ~ 1) 
0
Zheyuan Li On

The most straightforward way is

names(coef(fit))

If this only shows "(Intercept)", then you know.


Another way is to check "terms" object. In fact, this is lm independent. You create a formula:

f <- Response ~ 1

then terms(f) creates "terms" object. Later, lmObject inherits this.

Check out

attr(terms(fit), "intercept")
## to use formula only without actually fitting a model, do
## attr(terms(f), "intercept")

If this is 1, then you have intercept; if 0, you don't have it.

Now, check out

length(attr(terms(fit), "term.labels"))
## to use formula only without actually fitting a model, do
## attr(terms(f), "terms.labels")

If bigger than 0, you have other covariates; if 0, bingo.