Використання пакета data.table всередині мого власного пакету


76

Я намагаюся використовувати пакет 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

Хто-небудь може пояснити мені, чому це відбувається, і що я можу зробити, щоб це виправити. Будь-яка допомога дуже вдячна.


15
Я припускаю, що ви не оголосили залежність. Ви повинні видалити library(data.table)зі своєї функції та оголосити depends:data.tableу вашому просторі імен та ОПИС.
Андрі

Відповіді:


92

Припущення Андрі правильне, +1. У ньому є FAQ (див. vignette("datatable-faq")), А також нова віньєтка щодо імпорту data.table:

Поширені запитання 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показує, як це робиться. Він покладається на викличний пакет, що має простір імен, і, що Імпорт або Залежність простору імен data.table. Це, як data.tableможе бути передано не- data.table-залежні пакети (такі як функції в base) і ці пакети можуть використовувати абсолютно стандартний [.data.frameсинтаксис на data.tableблаженному невіданні , що data.frame is()а data.table, теж.

Це також те, чому data.tableнаслідування раніше не було сумісним з пакетами без простору імен, і чому за запитом користувача ми повинні були просити авторів таких пакетів додати простір імен до свого пакету, щоб бути сумісним. На щастя, тепер, коли R додає простір імен за замовчуванням для пакунків, яких немає (з v2.14.0), ця проблема зникла:

ЗМІНИ У ВАРІАНТІ 2.14.0
* Усі пакети повинні мати простір імен, і один створюється під час встановлення, якщо не надається у джерелах.


(Вибачте, це оживити, але ...) Метью, ти можеш пояснити, як це могло б працювати з інтерактивної позиції? Якщо мій пакет повертає data.tableкористувачеві в інтерактивному сеансі, чи потрібно буде їм використовувати data.tableсемантику, чи я можу якось підтримати знайомий data.frameсинтаксис?
Джефф Аллен,

1
@JeffAllen Це нове ... не впевнений. Якщо ваш пакет залежить від data.table, то це, мабуть, зробить інформацію про user.table. Можливо, імпортування data.table не буде (і, можливо, це те, що ви хотіли б).
Matt Dowle

Дякую Метт! Це вирішило мою проблему після півдня невдач та пошуку в мережі. Я помістив data.table лише в Імпорт. Код працював добре на R, але не з пакета. Переїхали до Depends, і це працює!
Оскар Ханссон

4
@OskarHansson Радий Depends працює , але Імпорт повинен працювати до тих пір , як ви були обидва імпорту в описі і import(data.table) в просторі імен, а?
Matt Dowle

3
@MattDowle Ви маєте рацію. Я отримав ПРИМІТКУ при використанні Depends. Я повернувся до Imports +, доданого @import data.tableв код, тому Roxygen додає import(data.table)в NAMESPACE.
Оскар Ханссон

31

Ось повний рецепт:

  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


Я дотримувався цих вказівок і отримую function not found. Я не міг знайти нічого подібного , так що я створив питання stackoverflow.com/questions/56720520 / ...
Kill3rbee Lee Mtoti

Дякую за це. Ви допомогли мені зрозуміти, що робити у зручному для читання форматі.
Річард Еріксон,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.