【问题标题】:Using S4 object output in source packages在源包中使用 S4 对象输出
【发布时间】:2013-06-21 01:02:38
【问题描述】:

我最近尝试将我的所有函数组织在包中,以避免在每个脚本之上有数百行代码。在运行一组 LME4 多级模型后,我编写了许多我使用的函数。这些函数旨在生成漂亮的输出表(我知道有可用的软件包可以做到这一点,但这些通常不够灵活,无法根据我的需要自定义表)。这是一个函数的示例,它采用 lmer 模型列表(例如 fm0、fm1、fm2)并将固定效应参数及其各自的标准误差组合在一个输出表中(我稍后将与其他模型统计信息一起使用生成自定义回归表)。

#' @rdname f.regTableFix1
#' @title Fixed effects table for lmer models
#' @description This function produces a regression table for multiple models of type lmer (lme4).
#' @param mList list of models to be used for the table
#' @return The output contains fixed effects (b,Std.Error) parameter.
#' @export
#' 
f.regTableFix1=function(mList){
  # Obtain fixed effects parameter
  for(m in 1:length(mList)){
    #m=2
    # Declare variables
    fix=fixef(mList[[m]]) #obtains fixed effect estimates
    stder=sqrt(diag(vcov(mList[[m]]))) #obtains respective standard errors
    if(m==1){
      masterFix=data.frame(variables=as.character(names(fix)),b=fix,se=stder,row.names=NULL,stringsAsFactors=F)
      names(masterFix)[!names(masterFix)=="variables"]=paste(names(masterFix)[!names(masterFix)=="variables"],m,sep=".")
    }else{
      addFix=data.frame(variables=as.character(names(fix)),b=fix,se=stder,row.names=NULL,stringsAsFactors=F)
      names(addFix)[!names(addFix)=="variables"]=paste(names(addFix)[!names(addFix)=="variables"],m,sep=".")
      masterFix=merge(masterFix,addFix,by="variables",all=T,sort=F)
    }
  }
  return(masterFix)
}

如果我只是在我的脚本中使用该函数(在顶部定义),它就可以正常工作。但是,在我将函数包含在一个包中后,它会引发以下错误(我通过使用 R CMD build 的系统调用以旧方式生成包,并使用 R CMD INSTALL 安装包)。

> tableFix=f.regTableFix1(modList)
Error in as.integer(x) : 
  cannot coerce type 'S4' to vector of type 'integer'

这个错误似乎与我的函数中使用了 S4 对象有关。不幸的是,固定效应参数和标准误差来自 lmer 模型(S4 对象),我无法更改。我尝试了多种不同的方法来获取固定效应参数和标准误差,包括以下:

coef(summary(mList[[m]]))
summary(mList[[m]])@coefs

如果我在脚本顶部声明的函数中使用这些不同的规范,它们都可以正常工作,但如果我将函数放入包中,它们都不起作用。只有错误消息会改变。例如,我在使用“coef(summary(mList[[m]]))”时收到错误消息“错误:$ 运算符对原子向量无效”。 我的包中的所有其他功能都可以正常工作,所以我想这不是我创建包的方式的一般问题。有没有人遇到过这种类型的问题?关于如何成功使用 S4 对象作为包中函数的输入,有什么建议吗?非常感谢任何帮助/建议/cmets!

最好, 拉斐尔

修改: 很抱歉首先没有提供一些示例数据。但现在是:

library(lme4)

# Prepare some example data
edata=Dyestuff #data automatically available through lme4
edata$var1=rnorm(30)
edata$var2=rnorm(30)
edata$var3=rnorm(30)

# Run multilevel models
fm0=lmer(Yield~1+(1|Batch), data=edata,
         na.action=na.omit, family="gaussian", verbose=F)

fm1=lmer(Yield~1+var1+(1|Batch), data=edata,
         na.action=na.omit, family="gaussian", verbose=F)

fm2=lmer(Yield~1+var1+var2+var3+(1|Batch), data=edata,
         na.action=na.omit, family="gaussian", verbose=F)

# Store model outputs in list
modList=list(fm0, fm1, fm2) 

# Obtain fixed effects output table with above discussed function
fixTable=f.regTableFix1(modList)

【问题讨论】:

  • 你能添加一个你的函数输入的例子吗?我使用fm1 <- lmList(distance ~ age | Subject, Orthodont) 对其进行了测试,但它给了我错误。

标签: r s4 lme4


【解决方案1】:

我认为您希望将依赖项导入包名称空间,这样做的廉价方法是添加

Imports: lme4

到您的包说明文件,并且

import(lme4)

到你的包 NAMESPACE 文件。更谨慎的做法是枚举所有依赖项,如 Writing R Extensions 中所述。

嗯,你正在使用 roxygen2;而且我不确定如何在这种情况下适当地指定导入。

【讨论】:

  • 免责声明:我对包装知之甚少(目前)。只需在函数中添加requires(lme4) 会起作用吗?
  • 是的,但是命名空间更好,因为它可以保证找到预期的功能(添加 require(lme4) 会将包添加到 search() 路径,所以有人(你)可以过来添加在 lme4) 中屏蔽预期功能的功能。
  • 嗨马丁摩根,非常感谢这个非常有用的信息/建议!我听从了您的建议,并将 lme4 添加到了 DESCRIPTION 和 NAMESPACE 文件中,并且效果很好!在 roxygen2 中向 NAMESPACE 添加任何内容非常简单:您只需在特定函数的顶部添加“#' @import lme4”,它就会自动写入 NAMESPACE。
  • 我还通读了“编写 R 扩展”。但是,由于我真的不知道从 lmer 模型输出对象中提取固定效果和标准错误需要 lme4 包中的哪些特定方法或类,所以我导入完整包以保存,很可能是“mer”类,但我必须检查一下。此外,在阅读“Writing R Extensions”时,我对何时在“Imports”和“DESCRIPTION”文件中的“Depends”标题下列出包依赖关系感到有些困惑。无论如何,这是一件小事,因为现在一切正常。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-07-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-16
相关资源
最近更新 更多