Create a call but evaluate only some elements
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 at 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