On 14/12/2021 3:26 p.m., Blackwell, Matthew wrote:
Hello all,

In attempting to create a one-sided formula from a two-sided formula,
I discovered that the following syntax will successfully complete this
operation:

f <- y ~ x + z
f[2] <- NULL
f
~x + z
str(f)
Class 'formula'  language ~x + z
   ..- attr(*, ".Environment")=<environment: R_GlobalEnv>

In searching through the formula documentation, I couldn't find this
technique as documented and wondered whether or not it is expected and
if it makes sense to develop a package against the behavior. I'm using
R 4.1.0, but I see the same on R-devel (r81303). I asked on Twitter,
but someone thought this list might be a better venue.

Apologies if I missed some documentation and thanks in advance.

The source "y ~ x + z" parses to a call to the `~` function with arguments y and x + z. Calls have the function as the first element, and arguments follow: so f[1] would be ~, f[2] would be y, f[3] would be x + z.

You can see this if you pass f through as.list():

> as.list(f)
[[1]]
`~`

[[2]]
y

[[3]]
x + z

Setting element 2 to NULL removes it, so you see

> f[2] <- NULL
> as.list(f)
[[1]]
`~`

[[2]]
x + z

I think it's safe to make use of this even if it's undocumented. It's a pretty basic aspect of formulas. I'd guess there are lots of packages already using it, but I can't point to any particular examples.

(I've ignored the difference between an unevaluated formula and an evaluated one, but they're almost the same, the only important difference in the attributes: evaluating it gives it a class and an environment.)

Duncan Murdoch

______________________________________________
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel

Reply via email to