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
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
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 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 > > ______________________________________________ > R-help at 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. >[[alternative HTML version deleted]]