使用粘贴公式创建的lme拟合无法进行anova测试

时间:2011-10-05 19:43:22

标签: r

我经常通过粘贴我需要的部分来指定公式参数来模拟拟合函数,如lmlme,如@ DWin对此问题的回答:Understanding lm and environment

在实践中,这看起来像这样:

library(nlme)
set.seed(5)
ns <- 5; ni <- 5; N <- ns*ni
d <- data.frame(y=rnorm(N),
                x1=rnorm(N),
                x2=factor(rep(1:ni, each=ns)),
                id=factor(rep(1:ns, ni)))

getm <- function(xs) {
  f <- paste("y ~", paste(xs, collapse="+"))
  lme(as.formula(f), random=~1|id, data=d, method="ML")
}
m1 <- getm("x1")
m2 <- getm(c("x1", "x2"))

但是,使用lme包中的nlme,比较使用anova的方式构建的两个模型不起作用,因为anova.lme查看已保存的公式参数确保模型适合相同的响应,并且保存的公式参数只是as.formula(f)。错误是:

> anova(m1, m2)
Error in inherits(object, "formula") : object 'f' not found

以下是anova命令应该做的事情(重新安装模型以使其有效):

> m1 <- lme(y~x1, random=~1|id, data=d, method="ML")
> m2 <- lme(y~x1+x2, random=~1|id, data=d, method="ML")
> anova(m1, m2)
   Model df      AIC      BIC    logLik   Test  L.Ratio p-value
m1     1  4 76.83117 81.70667 -34.41558                        
m2     2  8 72.69195 82.44295 -28.34597 1 vs 2 12.13922  0.0163

有什么建议吗?

2 个答案:

答案 0 :(得分:13)

Ben的答案有效,但do.call提供了他希望的更一般的解决方案。

getm <- function(xs) {
    f <- as.formula(paste("y ~", paste(xs, collapse="+")))
    do.call("lme", args = list(f, random=~1|id, data=d, method="ML"))
}

它起作用是因为(默认情况下)args =中的参数在传递给lme之前被计算。

答案 1 :(得分:3)

这是一个似乎有效的黑客攻击:

getm <- function(xs) {
  f <- paste("y ~", paste(xs, collapse="+"))
  m <- lme(as.formula(f), random=~1|id, data=d, method="ML")
  m$call$fixed <- eval(m$call$fixed)
  m
}

但我完全不喜欢它。我非常希望看到这个问题的更原则性的答案,因为我在尝试扩展bbmle包时遇到了这类问题。