Использование пакета data.table внутри моего собственного пакета
Я пытаюсь использовать пакет data.table внутри своего собственного пакета. MWE выглядит следующим образом:
Я создаю функцию test.fun, которая просто создает небольшой объект data.table, а затем суммирует группировку столбцов "Val" столбцом "A". Код
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
Может кто-нибудь объяснить мне, почему это происходит, и что я могу сделать, чтобы исправить это. Любая помощь очень ценится.
Ответы
Ответ 1
Андри догадывается, +1. В нем есть часто задаваемые вопросы (см. vignette("datatable-faq")
), а также новая виньетка при импорте data.table
:
FAQ 6.9: я создал пакет, который зависит от data.table. Как я убедитесь, что мой пакет осведомлен о data.table, так что наследование от data.frame работает?
Либо i) включите data.table
в поле Depends:
вашего файла DESCRIPTION, либо ii) включите data.table
в поле Imports:
вашего файла DESCRIPTION И import(data.table)
в своем файле NAMESPACE.
Дополнительная информация... в верхней части [.data.table
(и других функций data.table
) вы увидите переключатель в зависимости от результата вызова cedta()
. Это означает вызов таблицы данных среды. Печатание data.table:::cedta
показывает, как это было сделано. Он полагается на вызывающий пакет, имеющий пространство имен, и это пространство имен Import'ing или Depend'ing data.table
. Вот как data.table
можно передавать в пакеты, не поддерживающие data.table (например, функции в base
), и эти пакеты могут использовать абсолютно стандартный синтаксис [.data.frame
в data.table
, к счастью, не зная, что data.frame
is()
a data.table
тоже.
Именно поэтому наследование data.table
раньше не было совместимым с пакетами без пространства имен, и поэтому по запросу пользователя мы должны были попросить авторов таких пакетов добавить пространство имен в их пакет для совместимости. К счастью, теперь, когда R добавляет пространство имен по умолчанию для пакетов, в которых отсутствует один (из v2.14.0), эта проблема исчезла:
ИЗМЕНЕНИЯ В R Версии 2.14.0
* Все пакеты должны иметь пространство имен, и один создается при установке, если он не указан в исходных кодах.
Ответ 2
Вот полный рецепт:
1) Добавьте data.table
в Imports
в ваш 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