Case 1

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

Case 2

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 3

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

Case 4

formula(terms(y ~ -1 + (1 + x1), simplify = TRUE))
## y ~ x1

Case 5

The following interesting case was discussed by patsy author (python imitation of R formula).

formula(terms(y ~ 1 + (x1  - 1), simplify = TRUE))
## y ~ x1 - 1
formula(terms(y ~ x2 + (x1 - x2), simplify = TRUE))
## y ~ x2 + x1

Here the brackets are evaluated first. The way R internally works it seems is that intercept is a special case. (x1 - x2) can be thought of as subtract the term x2 but there is no x2 to subtract so evaluates it to just x1. If the same rule were to hold for intercept then (x1 - 1) should be x1 but in fact it is x1 - 1. So this evaluation rule seem contradictory.

formula(terms(y ~ 1 + (x1 - x2), simplify = TRUE))
## y ~ x1