Как заставить lm отображать в своем выводе формулу, переданную ему как переменную - PullRequest
4 голосов
/ 29 марта 2012

Пожалуйста, рассмотрите следующий пример кода (из документа 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))

Со следующим (сокращенным) выводом:

> 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)

Как видите,Второй вызов lm отображает не формулу, а переменную, содержащую формулу.Немного поэкспериментировав, я придумал третье решение, но мне оно показалось немного утомительным.

Поэтому возникает вопрос : есть ли другой способ заставить lm отображать формулу вместо переменной (т. Е. Без использования метода do.call, который я использовал выше).

(Причина, по которой я этого хочу, заключается в том, что я работаю над документом Sweave, поэтому я не могу видеть вызовы, только выходные данные, а затем заставляет lm сказать вам, какая формула очень удобна.)


ДАЖЕ ЛУЧШЕЕ РЕШЕНИЕ - Благодаря @ Aaron

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

РЕШЕНИЕ: Основываясь на ответе Г. Гротендика, я придумал следующую функцию:

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

Ответы [ 4 ]

5 голосов
/ 29 марта 2012

Поместите это в верхнюю часть вашего файла Sweave:

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

и затем вызовите lm обычно в оставшейся части файла.

Используя пример в вопросе и предполагая, что мы определили lm, как указано выше:

> lm(form1)

Call:
weight ~ group

Coefficients:
(Intercept)     groupTrt  
      5.032       -0.371  
3 голосов
/ 29 марта 2012

Это может быть так же утомительно, но, по крайней мере, содержит меньше символов;)

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

Call:
lm(formula = weight ~ group)

Coefficients:
(Intercept)     groupTrt  
      5.032       -0.371 
2 голосов
/ 17 апреля 2012

Вариант, основанный на окончательном решении ОП (по состоянию на 30 марта).

lm <- function(formula, ...) {
  mf <- match.call()
  mf[[1]] <- quote("stats::lm")
  env <- parent.frame()
  mf$formula <- eval(mf$formula, env)
  eval(mf, env)
}
2 голосов
/ 29 марта 2012

Вы можете изменить 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]])

затем

> lm(form1)

Call:
lm(formula = weight ~ group)

Coefficients:
(Intercept)     groupTrt  
      5.032       -0.371  
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...