[R] Create a call but evaluate only some elements

Shu Fai Cheung @hu|@|@cheung @end|ng |rom gm@||@com
Wed Oct 25 11:11:50 CEST 2023


Sorry for a typo, regarding the first attempt, lm_out2, using
do.call(), I meant:

'It does have the formula, "as a formula": y ~ x1 + x2.
However, the name "dat" is evaluated. ...'

Regards,
Shu Fai

On Wed, Oct 25, 2023 at 5:09 PM 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



More information about the R-help mailing list