如何在R函数内运行效果图绘制

5

更新:之前的标题是是否有特殊的方法将数据框作为函数参数传递?但根据这里聪明的人们的建议,这不是正确的问题。原始帖子如下。

当我使用somefunc(sleepstudy)运行以下函数时,

somefunc<-function (dataLme) 
{
 library(effects)
 library(lme4)

 fm8 <- lmer(Reaction ~ 1 + Days + (1 + Days|Subject), dataLme,
      REML = 0, verbose = TRUE)

 plot(effect("Days",fm8))
}

我遇到了一个错误。

Error in plot(effect("Days", fm8)) : 
  error in evaluating the argument 'x' in selecting a method for function 'plot': Error in is.data.frame(data) : object 'dataLme' not found

但如果我手动执行

library(effects)
library(lme4)
fm8 <- lmer(Reaction ~ 1 + Days + (1 + Days|Subject), sleepstudy,
    REML = 0, verbose = TRUE)
plot(effect("Days",fm8))

我没有收到任何错误提示。

我原以为 R 是按值传递,意味着将整个对象内容复制到函数参数中。但看起来我并不完全正确。有人能解释一下发生了什么吗?


3
我认为问题不在于R的参数传递语义,而在于effect试图在错误的位置对模型拟合调用进行eval。或者至少是在一个导致其无法在函数内正确运行的位置上进行了调用。 - joran
@RicardoSaporta 天。抱歉打错了字,我已经在我的问题中修正了。谢谢! - Tae-Sung Shin
@joran 我明白了。你是怎么这么快就弄明白的呢? :-) 哦,好吧。我想现在是时候联系作者了。感谢你的帮助! - Tae-Sung Shin
3
options(error=recover) 在调试时非常有用,可以快速帮助识别这些类型的问题。 - Dason
2
我使用了traceback,将问题缩小到(未导出的函数)mer.to.glm内部的eval(cl)。如果你逐步执行,就会发现在eval(cl)中更改环境参数似乎可以解决问题。 - joran
@joran 如果不麻烦的话,您能否创建一个包含您发现的答案?这也将有助于其他人。谢谢。 - Tae-Sung Shin
2个回答

5
一种(不太正式的)解决方法是将dataLme赋值到全局环境中,这样effect()就能找到它了:
library(effects)
library(lme4)

somefunc <- function (dataLme) {
    ## Assign to a symbol that's unlikely to be in use in .GlobalEnv
    ## (and make sure this function cleans up after itself!)
    assign(".TeMpVaR", dataLme, envir=globalenv())
    on.exit(rm(.TeMpVaR, envir=globalenv()))

    fm8 <- lmer(Reaction ~ 1 + Days + (1 + Days|Subject), .TeMpVaR,
         REML = 0, verbose = TRUE)    
    plot(effect("Days",fm8))
}

somefunc(sleepstudy)

2

这只是部分答案,但我想记录一下我的测试过程。我主要想展示的是问题特别出现在effects包中,而不是lme4包(我维护的包,也遇到了这些问题:大多数这样的问题都已经在开发版本的lme4中得到解决,但有些问题仍然存在于稳定版本中,在我的系统上安装为lme4.0...)

library("effects")

showpkgs <- function() names(sessionInfo()$otherPkgs)
somefunc<-function (dataLme, pkg="nlme")  {
    require(pkg,character.only=TRUE)
    on.exit(detach(paste("package",pkg,sep=":"),unload=TRUE,character.only=TRUE))
    if (pkg=="nlme") {
        fm8 <- lme(Reaction ~ 1 + Days,random=~Days|Subject, dataLme)
    } else {
        fm8 <- lmer(Reaction ~ 1 + Days + (1 + Days|Subject), dataLme, REML = 0)
    }
    plot(effect("Days",fm8))
}

无论我们使用稳定版本的lme4,开发版本的lme4,还是旧版的nlme软件包,都会出现这个错误。
data("sleepstudy",package="lme4")
showpkgs()
somefunc(sleepstudy)  ## nlme
showpkgs()  ## warning about unloading nlme namespace due to glmmADMB dep. (??)
somefunc(sleepstudy,pkg="lme4.0")  ## lme4-stable
showpkgs()  ## failure to remove Matrix/warning message
somefunc(sleepstudy,pkg="lme4")    ## lme4-devel
showpkgs()  ## leaves RcppEigen, Rcpp loaded as well

我研究了一下effects包,很难找到一个简单的通用解决方案。将相关的eval(cl)行更改为eval(cl,envir=environment(formula(mod)))可以在开发版的lme4上运行,但不适用于稳定版的lme4nlme...


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