[R] Create a call but evaluate only some elements

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


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