如何在函数中使用lmer

5

我想写一个函数来收集我在脚本中经常使用的一些调用
我在示例中使用了lme4包的sleepstudy数据
下面是我开始使用的(精简版)函数:

trimModel1 <- function(frm, df) {
  require(LMERConvenienceFunctions)
  require(lme4)

  lm<-lmer(frm,data=df)
  lm.trimmed = romr.fnc(lm, df)
  df = lm.trimmed$data
  # update initial model on trimmed data
  lm<-lmer(frm,data=df)
#   lm@call$formula<-frm
  mcp.fnc(lm)
  lm
}

当我像下面这样调用这个函数时:
(fm1<-trimModel1(Reaction ~ Days + (Days|Subject),sleepstudy))

输出的前三行如下所示:
Linear mixed model fit by REML 
Formula: frm    
Data: df

如果我在控制台中调用了trimModel1函数的命令,那么模型摘要的前三行如下:

Linear mixed model fit by REML 
Formula: Reaction ~ Days + (Days | Subject) 
   Data: sleepstudy 

这个差异是一个问题,因为使用lme4包的几个软件包都使用公式和数据字段。例如,effects软件包使用这些字段,当我使用上面的trimModel1函数时,下面的命令将无法正常工作:

library(effects)
plot(allEffects(fm1))

我在stackoverflow和R讨论组上寻找解决方案,并发现您可以更改模型的公式字段。如果在trimModel1函数中取消注释lm@call$formula<-frm行,则摘要中的公式字段将显示正确。不幸的是,当我现在运行来自effects包的函数时,仍然会出现错误:

Error in terms.formula(formula, data = data) : 
  'data' argument is of the wrong type

这是因为数据字段仍然不正确。
我发现另一个可能的解决方案是这个函数:
trimModel2 <- function(frm, df) {
  require(LMERConvenienceFunctions)
  require(lme4)

  lm<-do.call("lmer",list(frm,data=df))
  lm.trimmed = romr.fnc(lm, df)
  df = lm.trimmed$data
  # update initial model on trimmed data
  lm<-do.call("lmer",list(frm,data=df))
  mcp.fnc(lm)
  lm
}

当我现在在控制台中输入以下命令时,不会出现任何错误:
(fm2<-trimModel2(Reaction ~ Days + (Days|Subject),sleepstudy))
plot(allEffects(fm2))

allEffects函数已经起作用了,但现在的问题是fm2模型的概要显示了原始的sleepstudy数据。对于sleepstudy数据来说这并不是什么大问题,但是如果有非常大的数据集,有时在显示模型时Rstudio会崩溃。


有人知道如何使其中一个(或两个)函数正确工作吗?


我想我必须更改fm1@call$data字段,但我不知道怎么做。


对于那些在谷歌中查找数据参数的人:当数据集具有保留名称(在我的情况下为“all”)时,effects也会引发此错误。 - Ruben
1个回答

5

像这样执行:

trimModel1 <- function(frm, df) {
  require(LMERConvenienceFunctions)
  require(lme4)
  dfname <- as.name(deparse(substitute(df)))

  lm<-lmer(frm,data=df)
  lm.trimmed = romr.fnc(lm, df)
  df = lm.trimmed$data
  # update initial model on trimmed data
  lm<-lmer(frm,data=df)
  lm@call$formula <- frm
  lm@call$data <- dfname
  mcp.fnc(lm)
  lm
}

这是一种“解析替换技巧”,可以从对象本身获取对象名称。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接