The following are the same:

formula(terms(y ~ (x1 + x2)^2, simplify = TRUE))
## y ~ x1 + x2 + x1:x2
formula(terms(y ~ (1 + x1 + x2)^2, simplify = TRUE))
## y ~ x1 + x2 + x1:x2

What is happening for the latter?

Is it evaluated as follows?

  1. y ~ 1 + x1 + x2 + 1:x1 + 1:x2 + x1:x2
  2. y ~ 1 + x1 + x2 + 1 + 1 + x1:x2 (since 1:x1 = 1)
  3. y ~ 1 + x1 + x2 + x1:x2 (since x + x = x)
  4. y ~ x1 + x2 + x1:x2 (since 1 is included by default?)

But looking at the AST

lobstr::ast(y ~ (1 + x1 + x2)^2)
## █─`~` 
## ├─y 
## └─█─`^` 
##   ├─█─`(` 
##   │ └─█─`+` 
##   │   ├─█─`+` 
##   │   │ ├─1 
##   │   │ └─x1 
##   │   └─x2 
##   └─2

and seeing that y ~ 1 + x are simplifeid as y ~ x in R, then it is actually like

  1. y ~ ((1 + x1) + x2)^2
  2. y ~ (x1 + x2)^2
  3. y ~ x1 + x2 + x1:x2

WAT: Unexpected cases

Case 1

y ~ (0 + x1 + x2)^2

then it is evaluated hypothetically as

  1. y ~ ((0 + x1) + x2)^2
  2. y ~ (-1 + x1 + x2)^2
  3. y ~ (-1 + x1 + x2)^2 (doesn’t change)
  4. y ~ -1 + x1 + x2 + -1:x1 + -1:x2 + x1:x2
  5. y ~ -1 + x1 + x2 + 1 - 1 + 1 - 1 + x1:x2 (maybe??)
  6. y ~ -1 + x1 + x2 + x1:x2

Case 2

formula(terms(y ~ -1:x, simplify = TRUE))
## y ~ 1 - 1