[R] Creating model formulas programmatically

Bert Gunter bgunter@4567 @end|ng |rom gm@||@com
Sun Mar 30 17:41:24 CEST 2025


Gabor, Duncan, et. al.

1. Thank you for your great comments and solutions. This is what I was
hoping for!

2. Duncan: I completely agree with your criticisms. In fact, I realized the
for() loop only needed the <- assignment, but your comment is important to
note. However, I didn't like the for() loop either; I *much* preferred your
Reduce() solution which is exactly the sort of elegant functionally based
solution that R excels at. I am glad that you put it into the record.

3. If I may indulge those who are following this thread, yet another simple
approach that just uses call() recursively is:

recurseCall <- function(nms, FUN = '+')
{
   if(length(nms) > 2) call(FUN, nms[[1]], Recall(nms[-1]))
   else call(FUN, nms[[1]],nms[[2]])
}
## yielding
> recurseCall(nms)
Heigh + (Ho + (Silver + Away))

While this result is different than that given by the others, it is
syntactically equivalent and yields identical results when used.
However, Duncan's Reduce() solution seems to me "obviously" better. In
fact, I think recurseCall just recapitulates the logic of Reduce().

4. And, again, I realize that versions of str2lang(paste(somename, collapse
= ' + ')) work just fine, but I was explicitly interested in eliciting the
bushel basket of elegant (imo) approaches that have been offered.

Again, my thanks to all.

Bert








"An educated person is one who can entertain new ideas, entertain others,
and entertain herself."



On Sun, Mar 30, 2025 at 6:11 AM Gabor Grothendieck <ggrothendieck using gmail.com>
wrote:

> Another solution.  reformulate + substitute + as.formula:
>
> substitute(~ (.)^2, list(. = reformulate(somenames)[[2]])) |> as.formula()
>
> On Sat, Mar 29, 2025 at 5:31 PM Bert Gunter <bgunter.4567 using gmail.com>
> wrote:
> >
> > Note: I am almost certain that this has been asked and answered here
> > before, so my apologies for the redundant query.
> >
> > I also know that there are several packages that will do this, but I wish
> > to do it using base R functions only (see below).
> >
> > The query: Suppose I have a character vector of names like this:
> > somenames <- c("Heigh", "Ho", "Silver", "Away")
> > (maybe dozens or hundreds: i.e. lots of names)
> >
> > Now suppose want to put these in a model formula like this:
> > ~ (Heigh + Ho + Silver + Away)^2
> >
> > ... But **without** pasting them into a character vector and using
> > parse(text = ...) , which, I grant, is sometimes the simplest way.
> > Instead, I want to do it using Base R's computing on the language
> > functions. I can do this with bquote() or substitute(), for example, like
> > this:
> >
> > somenames <- c("Heigh", "Ho", "Silver", "Away")
> > nms <- lapply(somenames, as.name)
> > form <- nms[[1]]
> > for(x in nms[-1])
> >    form <<- bquote(.(form) + .(x), list(form = form, x = x))
> > ## or form <<- substitute(form + x, list(form = form, x = x))
> > form <- bquote(~ (.(form))^2, list(form =form))
> >
> > ## yielding
> > > form
> > ~(Heigh + Ho + Silver + Away)^2
> >
> > My question: Is there a simpler/slicker way to do this? This seems kinda
> > kludgy, and I have the feeling that I'm missing something obviously
> better
> > (in base R only; obviously better stuff is in various packages)
> >
> > Best to all,
> > Bert
> >
> > "An educated person is one who can entertain new ideas, entertain others,
> > and entertain herself."
> >
> >         [[alternative HTML version deleted]]
> >
> > ______________________________________________
> > R-help using r-project.org mailing list -- To UNSUBSCRIBE and more, see
> > https://stat.ethz.ch/mailman/listinfo/r-help
> > PLEASE do read the posting guide
> https://www.R-project.org/posting-guide.html
> > and provide commented, minimal, self-contained, reproducible code.
>
>
>
> --
> Statistics & Software Consulting
> GKX Group, GKX Associates Inc.
> tel: 1-877-GKX-GROUP
> email: ggrothendieck at gmail.com
>

	[[alternative HTML version deleted]]



More information about the R-help mailing list