How to make lm display in your output by a formula passed to it as a variable

Please consider the following example code (from the doc lm

):

ctl <- c(4.17,5.58,5.18,6.11,4.50,4.61,5.17,4.53,5.33,5.14)
trt <- c(4.81,4.17,4.41,3.59,5.87,3.83,6.03,4.89,4.32,4.69)
group <- gl(2,10,20, labels=c("Ctl","Trt"))
weight <- c(ctl, trt)
lm(weight ~ group)
form1 <- weight ~ group
lm(form1)
do.call("lm",list(formula=form1))

      

With the following (abbreviated) output:

> lm(weight ~ group)

Call:
lm(formula = weight ~ group)

> lm(form1)

Call:
lm(formula = form1)

> do.call("lm",list(formula=form1))

Call:
lm(formula = weight ~ group)

      

As you can see, the second call lm

does not display the formula, but the variable containing the formula. With some experimentation, I came up with a third solution, but I find it a little tedious.

The question, therefore, is : is there any other way to make the lm

formula display instead of a variable (i.e. without using the method do.call

I used above).

(The reason I want is because I'm working on a Sweave document, so I don't see the calls, only the outputs, and then lm tells you which formula is being used very conveniently.)


EVEN BEST SOLUTION - Thanks to @Aaron

lm <- function(...) {
  mf <- match.call()
  mf[[1]] <- quote(stats::lm)
  env <- parent.frame()
  mf$formula <- eval(mf$formula, env)
  eval(mf, env)
}

      

SOLUTION: Based on the answer by G. Grothendieck, I came up with the following function:

lm <- function(...) {
    mf <- match.call()
    mf[[1]] <- quote(stats::lm)
    env <- parent.frame()
    fm <- eval(mf, env)
    fm$call$formula <- formula(fm)
    fm
}

      

+3


source to share


4 answers


Place this at the top of your Sweave file:

<<preliminaries,echo=FALSE,results=hide>>=
lm <- function(fo, ...) { fm <- stats::lm(fo, ...); fm$call <- fo; fm }
@

      

and then call lm

normally on the rest of the file.



Using the example in the question and assume we have defined lm

as above:

> lm(form1)

Call:
weight ~ group

Coefficients:
(Intercept)     groupTrt  
      5.032       -0.371  

      

+5


source


It can be just as tedious, but at least it contains fewer characters;)



R> eval(call("lm",form1))

Call:
lm(formula = weight ~ group)

Coefficients:
(Intercept)     groupTrt  
      5.032       -0.371 

      

+3


source


You can change print.lm

:

body(print.lm)[[2]] <- 
  as.call(expression({
    ca<-x$call
    ca$formula <- formula(x)
    cat("\nCall:\n", paste(deparse(ca), sep = "\n", collapse = "\n"), "\n\n", sep = "")
  })[[1]])

      

then

> lm(form1)

Call:
lm(formula = weight ~ group)

Coefficients:
(Intercept)     groupTrt  
      5.032       -0.371  

      

+2


source


Option based on OP's final decision (as of March 30th).

lm <- function(formula, ...) {
  mf <- match.call()
  mf[[1]] <- quote("stats::lm")
  env <- parent.frame()
  mf$formula <- eval(mf$formula, env)
  eval(mf, env)
}

      

+2


source







All Articles