在我自己的包中使用data.table包


76

我正在尝试在自己的包中使用data.table包。MWE如下:

我创建了一个函数test.fun,该函数只是创建了一个小的data.table对象,然后将按“ A”列分组的“ Val”列求和。该代码是

test.fun<-function ()
{
    library(data.table)
    testdata<-data.table(A=rep(seq(1,5), 5), Val=rnorm(25))
    setkey(testdata, A)
    res<-testdata[,{list(Ct=length(Val),Total=sum(Val),Avg=mean(Val))},"A"]
    return(res)
}

当我在常规的R会话中创建此函数,然后运行该函数时,它会按预期工作。

> res<-test.fun()
data.table 1.8.0  For help type: help("data.table")
> res
     A Ct      Total        Avg
[1,] 1  5 -0.5326444 -0.1065289
[2,] 2  5 -4.0832062 -0.8166412
[3,] 3  5  0.9458251  0.1891650
[4,] 4  5  2.0474791  0.4094958
[5,] 5  5  2.3609443  0.4721889

当我将此功能放入程序包中时,安装程​​序包,加载程序包,然后运行该功能,我会收到一条错误消息。

> library(testpackage)
> res<-test.fun()
data.table 1.8.0  For help type: help("data.table")
Error in `[.data.frame`(x, i, j) : object 'Val' not found

任何人都可以向我解释为什么会发生这种情况以及我可以做些什么来解决它。很感谢任何形式的帮助。


15
我的猜测是您尚未声明依赖项。您应该library(data.table)从函数中删除,并depends:data.table在名称空间和DESCRIPTION中声明。
Andrie

Answers:


92

安德烈的猜测是对的,+ 1。上面有一个FAQ(请参阅参考资料vignette("datatable-faq")),以及有关导入的新小插图data.table

FAQ 6.9:我创建了一个依赖于data.table的包。如何确保我的程序包可识别data.table,以便从data.frame继承?

i)包括data.tableDepends:DESCRIPTION文件的字段中,或者ii)包括data.tableImports:DESCRIPTION文件的字段和import(data.table)NAMESPACE文件中。

[.data.table(和其他data.table功能)顶部的进一步背景... ,您将看到一个切换,具体取决于调用的结果cedta()。这代表呼叫环境数据表感知。打字data.table:::cedta揭示了它是如何完成的。它依赖于具有名称空间的调用程序包,并且该名称空间Import'ing或Depend'依靠data.table。这是如何data.table可以传递到非data.table感知包(如函数base)和这些软件包可以用绝对标准[.data.frame的语法data.table,一无所知的data.frame is()data.table

这也是为什么data.table继承以前不与无名称空间的软件包兼容的原因,以及为什么应用户要求,我们不得不要求此类软件包的作者向其软件包添加名称空间以使其兼容。令人高兴的是,现在R为缺少包的软件包添加了默认名称空间(从v2.14.0起),该问题已消失:

R版本2.14.0中的更改
*所有软件包都必须具有一个名称空间,并且如果未在源中提供,则在安装时会创建一个名称空间。


(很抱歉让您复活了,但是...)马修,您能从互动的角度阐明它的工作方式吗?如果我的程序包data.table在交互式会话中向用户返回,是否要求他们使用data.table语义,或者是否可以通过某种方式支持熟悉的data.frame语法?
杰夫·艾伦

1
@JeffAllen这是一个新的...不确定。如果您的软件包依赖于data.table,那么我猜这会使用户知道data.table。也许不会导入data.table(也许就是您想要的)。
Matt Dowle

谢谢马特!经过半天的故障并搜索了网络,这解决了我的问题。我只将data.table放在了Imports中。该代码在R中运行良好,但在软件包内部却无法正常运行。移至Depends,它起作用了!
奥斯卡·汉森

4
@OskarHansson Glad Depends可以工作,但是只要您同时在Description import(data.table)NAMESPACE中都具有Imports,Import应该可以工作?
马特·道尔

3
@MattDowle你是对的。使用Depends时出现提示。我改回到@import data.table在代码中添加的Imports + ,以便Roxygenimport(data.table)在NAMESPACE中添加。
奥斯卡·汉森

31

这是完整的食谱:

  1. 添加data.tableImports您的DESCRIPTION文件中。

  2. 添加@import data.table到您各自的.R文件(即,包含引发错误的函数的.R文件Error in [.data.frame(x, i, j) : object 'Val' not found)。

  3. 键入library(devtools)并设置您的工作目录以指向R包的主目录。

  4. 输入document()。这将确保您的NAMESPACE文件包含import(data.table)一行。

  5. 类型 build()

  6. 类型 install()

关于什么是好的底漆build()install()做,请参阅:http://kbroman.org/pkg_primer/

然后,一旦您关闭R会话并下次登录,就可以立即跳入:

  1. 类型 library("my_R_package")

  2. 键入上述.R文件中包含的函数的名称。

  3. 请享用!您不应再收到恐惧Error in [.data.frame(x, i, j) : object 'Val' not found


我按照这些说明进行操作function not found。我找不到类似的话,所以我创建了一个问题stackoverflow.com/questions/56720520/...
Kill3rbee李Mtoti

这次真是万分感谢。您帮助我以一种易于阅读的格式查看该怎么做。
理查德·埃里克森
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.