[R] Create a call but evaluate only some elements

Shu Fai Cheung @hu|@|@cheung @end|ng |rom gm@||@com
Thu Oct 26 04:28:20 CEST 2023


Dear Bert,

Many thanks for your suggestion! I am reading the section to
understand more about this topic. It is highly relevant to what I plan
to work on.

Regards,
Shu Fai

On Thu, Oct 26, 2023 at 5:38 AM Bert Gunter <bgunter.4567 using gmail.com> wrote:
>
> As you seem to have a need for this sort of capability (e.g. bquote),
> see Section 6: "Computing on the Language" in the R Language
> Definition manual. Actually, if you are interested in a concise
> (albeit dense) overview of the R Language, you might consider going
> through the whole manual.
>
> Cheers,
> Bert
>
> On Wed, Oct 25, 2023 at 3:57 AM Shu Fai Cheung <shufai.cheung using gmail.com> wrote:
> >
> > Dear Iris,
> >
> > Many many thanks! This is exactly what I need! I have never heard
> > about bquote(). This function will also be useful to me on other
> > occasions.
> >
> > I still have a lot to learn about the R language ...
> >
> > Regards,
> > Shu Fai
> >
> >
> > On Wed, Oct 25, 2023 at 5:24 PM Iris Simmons <ikwsimmo using gmail.com> wrote:
> > >
> > > You can try either of these:
> > >
> > > expr <- bquote(lm(.(as.formula(mod)), dat))
> > > lm_out5 <- eval(expr)
> > >
> > > expr <- call("lm", as.formula(mod), as.symbol("dat"))
> > > lm_out6 <- eval(expr)
> > >
> > > but bquote is usually easier and good enough.
> > >
> > > On Wed, Oct 25, 2023, 05:10 Shu Fai Cheung <shufai.cheung using gmail.com> wrote:
> > >>
> > >> Hi All,
> > >>
> > >> I have a problem that may have a simple solution, but I am not
> > >> familiar with creating calls manually.
> > >>
> > >> This is example calling lm()
> > >>
> > >> ``` r
> > >> set.seed(1234)
> > >> n <- 10
> > >> dat <- data.frame(x1 = rnorm(n),
> > >>                   x2 = rnorm(n),
> > >>                   y = rnorm(n))
> > >>
> > >> lm_out <- lm(y ~ x1 + x2, dat)
> > >> lm_out
> > >> #>
> > >> #> Call:
> > >> #> lm(formula = y ~ x1 + x2, data = dat)
> > >> #>
> > >> #> Coefficients:
> > >> #> (Intercept)           x1           x2
> > >> #>     -0.5755      -0.4151      -0.2411
> > >> lm_out$call
> > >> #> lm(formula = y ~ x1 + x2, data = dat)
> > >> ```
> > >>
> > >> The call is stored, "lm(formula = y ~ x1 + x2, data = dat)", and names
> > >> are not evaluated.
> > >>
> > >> I want to create a similar call, but only one of the elements is from a string.
> > >>
> > >> ```r
> > >> mod <- "y ~ x1 + x2"
> > >> ```
> > >>
> > >> This is what I tried but failed:
> > >>
> > >> ```r
> > >> lm_out2 <- do.call("lm",
> > >>                    list(formula = as.formula(mod),
> > >>                         data = dat))
> > >> lm_out2
> > >> #>
> > >> #> Call:
> > >> #> lm(formula = y ~ x1 + x2, data = structure(list(x1 = c(-1.20706574938542,
> > >> #> 0.27742924211066, 1.08444117668306, -2.34569770262935, 0.42912468881105,
> > >> #> 0.506055892157574, -0.574739960134649, -0.546631855784187,
> > >> -0.564451999093283,
> > >> #> -0.890037829044104), x2 = c(-0.477192699753547, -0.998386444859704,
> > >> #> -0.77625389463799, 0.0644588172762693, 0.959494058970771, -0.110285494390774,
> > >> #> -0.511009505806642, -0.911195416629811, -0.83717168026894, 2.41583517848934
> > >> #> ), y = c(0.134088220152031, -0.490685896690943, -0.440547872353227,
> > >> #> 0.459589441005854, -0.693720246937475, -1.44820491038647, 0.574755720900728,
> > >> #> -1.02365572296388, -0.0151383003641817, -0.935948601168394)), class
> > >> = "data.frame", row.names = c(NA,
> > >> #> -10L)))
> > >> #>
> > >> #> Coefficients:
> > >> #> (Intercept)           x1           x2
> > >> #>     -0.5755      -0.4151      -0.2411
> > >> ```
> > >>
> > >> It does not have the formula, "as a formula": y ~ x1 + x2.
> > >> However, the name "dat" is evaluated. Therefore, the call stored does
> > >> not have the name 'dat', but has the evaluated content.
> > >>
> > >> The following fits the same model. However, the call stores the name,
> > >> 'mod', not the evaluated result, y ~ x1 + x2.
> > >>
> > >> ```r
> > >> lm_out3 <- lm(mod, data = dat)
> > >> lm_out3
> > >> #>
> > >> #> Call:
> > >> #> lm(formula = mod, data = dat)
> > >> #>
> > >> #> Coefficients:
> > >> #> (Intercept)           x1           x2
> > >> #>     -0.5755      -0.4151      -0.2411
> > >> ```
> > >>
> > >> The following method works. However, I have to do a dummy call,
> > >> extract the stored call, and set formula to the result of
> > >> as.formula(mod):
> > >>
> > >> ```r
> > >> lm_out3 <- lm(mod, data = dat)
> > >> lm_out3
> > >> #>
> > >> #> Call:
> > >> #> lm(formula = mod, data = dat)
> > >> #>
> > >> #> Coefficients:
> > >> #> (Intercept)           x1           x2
> > >> #>     -0.5755      -0.4151      -0.2411
> > >>
> > >> call1 <- lm_out3$call
> > >> call1$formula <- as.formula(mod)
> > >> lm_out4 <- eval(call1)
> > >> lm_out4
> > >> #>
> > >> #> Call:
> > >> #> lm(formula = y ~ x1 + x2, data = dat)
> > >> #>
> > >> #> Coefficients:
> > >> #> (Intercept)           x1           x2
> > >> #>     -0.5755      -0.4151      -0.2411
> > >> ```
> > >>
> > >> Is it possible to create the call directly, with only 'mod' evaluated,
> > >> and other arguments, e.g., 'dat', not evaluated?
> > >>
> > >> Regards,
> > >> Shu Fai
> > >>
> > >> ______________________________________________
> > >> 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 http://www.R-project.org/posting-guide.html
> > >> and provide commented, minimal, self-contained, reproducible code.
> >
> > ______________________________________________
> > 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 http://www.R-project.org/posting-guide.html
> > and provide commented, minimal, self-contained, reproducible code.



More information about the R-help mailing list