user321627
user321627

Reputation: 2564

Create expression test to see if `as.formula('X ~ 1')` in R contains an intercept?

In R, one can specify a formula:

F <- as.formula('X ~ 1')

I am trying to come up with a way to test if F above contains an intercept only, i.e., ~ 1. I was trying to use grepl to no avail. Is there a way to definitely test if the above formula contains only an intercept? i.e., I am hoping to come up with a method that would return true in the following different cases:

F <- as.formula('X~ 1')
F <- as.formula('X~1')
F <- as.formula('X ~1')

as well. Thanks!

Upvotes: 3

Views: 133

Answers (3)

TJGorrie
TJGorrie

Reputation: 396

attr(terms(x~y), 'intercept') will do what you want.

formula <- x~y
formula2 <- x~y-1 # no intercept
attr(terms(formula), 'intercept')
## [1] 1
attr(terms(formula2), 'intercept')
## [1] 0

EDIT: I initially misread the question. If you are looking for a specific example that will look for whether a formula contains only an intercept you could use:

f1 <- x ~ y
f2 <- x ~ y-1
f3 <- x ~ 1
f3 <- x ~ 0

onlyIntercept <- function(f){
  return(attr(terms(f), 'intercept') & length(attr(terms(f), 'factors')) == 0)
}
# Examples on above, then on OPs examples:
onlyIntercept(f1)
## [1] FALSE
onlyIntercept(f2)
## [1] FALSE
onlyIntercept(f3)
## [1] TRUE
onlyIntercept(f4)
## [1] FALSE

onlyIntercept(as.formula('X~ 1'))
## [1] TRUE
onlyIntercept(as.formula('X~1'))
## [1] TRUE
onlyIntercept(as.formula('X ~1'))
## [1] TRUE

The onlyIntercept function I define here checks if the intercept attribute is 0 or 1 and checks if there are any additional factors(variables) that would normally be included in a model. If none are present this attribute has a length of 0 and can easily be checked.

Upvotes: 5

St&#233;phane Laurent
St&#233;phane Laurent

Reputation: 84539

You can use the lazyeval package:

> F <- as.formula('X ~ 1')
> lazyeval::f_rhs(F)
[1] 1

Upvotes: 3

akrun
akrun

Reputation: 887221

We can extract and check

F[[3]] == 1

because if we do as.list, the 3rd list element is 1

as.list(F)
#[[1]]
# `~`

#[[2]] 
#X

#[[3]]
#[1] 1

it will return TRUE in all the 3 'F's in the OP"s post

Upvotes: 2

Related Questions