87 votes

Utilisation du paquet data.table dans mon propre paquet

J'essaie d'utiliser le paquet data.table dans mon propre paquet. Le MWE est le suivant :

Je crée une fonction, test.fun, qui crée simplement un petit objet data.table, puis additionne la colonne "Val" en la regroupant par la colonne "A". Le code est le suivant

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)
}

Lorsque je crée cette fonction dans une session R normale, puis que j'exécute la fonction, elle fonctionne comme prévu.

> 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

Lorsque je place cette fonction dans un paquet, que j'installe le paquet, que je charge le paquet, puis que j'exécute la fonction, j'obtiens un message d'erreur.

> 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

Quelqu'un peut-il m'expliquer pourquoi cela se produit et ce que je peux faire pour y remédier ? Toute aide est la bienvenue.

15 votes

Je pense que vous n'avez pas déclaré de dépendance. Vous devriez supprimer library(data.table) de votre fonction, et déclarez depends:data.table dans votre espace de noms et votre DESCRIPTION.

1 votes

Il y a aussi maintenant le .datatable.aware = TRUE pour traiter cette question, comme indiqué dans ce et dans le vignette liés ci-dessous. Déclarer Depends: data.table attachera l'ensemble du paquet au chemin de recherche, ce qui est parfois découragé .

97voto

Matt Dowle Points 20936

La supposition d'Andrie est juste, +1. Il y a une FAQ à ce sujet (voir vignette("datatable-faq") ), ainsi qu'une nouvelle vignette sur l'importation data.table :

FAQ 6.9 : J'ai créé un paquet qui dépend de data.table. Comment puis-je m'assurer que mon paquet est conscient de data.table pour que l'héritage à partir de data.frame fonctionne ?

Soit i) inclure data.table dans le Depends: de votre fichier DESCRIPTION, ou ii) inclure le champ data.table dans le Imports: de votre fichier DESCRIPTION ET import(data.table) dans votre fichier NAMESPACE.

Pour en savoir plus ... en haut de la page [.data.table (et autres data.table ), vous verrez un changement en fonction du résultat d'un appel aux fonctions cedta() . Cela signifie Calling Environment Data Table Aware. Tapez data.table:::cedta révèle comment on fait. Elle repose sur le fait que le paquet appelant possède un espace de noms, et que cet espace de noms importe ou dépend de data.table . C'est ainsi que data.table peuvent être passés à des non données.table-aware (telles que les fonctions dans base ) et ces paquets peuvent utiliser le système absolument standard [.data.frame sur la syntaxe data.table ignorant parfaitement que le data.frame is() a data.table aussi.

C'est aussi pourquoi data.table inheritance n'était pas compatible avec les paquets sans espace de nom, et c'est pourquoi, à la demande des utilisateurs, nous devions demander aux auteurs de ces paquets d'ajouter un espace de nom à leur paquet pour être compatibles. Heureusement, maintenant que R ajoute un espace de noms par défaut pour les paquets qui n'en ont pas (à partir de la v2.14.0), ce problème a disparu :

CHANGEMENTS DANS LA VERSION R 2.14.0
* Tous les paquets doivent avoir un espace de nom, et celui-ci est créé à l'installation s'il n'est pas fourni dans les sources.

0 votes

(Désolé de relancer cette question, mais...) Matthew, pouvez-vous préciser comment cela fonctionnerait d'un point de vue interactif ? Si mon paquet renvoie un data.table à un utilisateur dans le cadre d'une session interactive, sera-t-il tenu d'utiliser l'option data.table sémantique, ou y a-t-il un moyen pour que je puisse supporter la familière data.frame la syntaxe ?

1 votes

@JeffAllen C'est une nouvelle question... je ne suis pas sûr. Si votre paquet dépend de data.table, alors l'utilisateur sera conscient de data.table, je suppose. Peut-être que l'importation de data.table ne le ferait pas (et c'est peut-être ce que vous souhaitez).

0 votes

Merci Matt ! Cela a résolu mon problème après une demi-journée d'échecs et de recherches sur le net. J'avais mis data.table uniquement dans les Importations. Le code fonctionnait bien dans R mais pas à l'intérieur du paquet. Je l'ai déplacé dans Depends et ça marche !

38voto

white_rabbit Points 140

Voici la recette complète :

  1. Ajouter data.table à Imports dans votre DESCRIPTION fichier.

  2. Ajouter @import data.table à votre fichier .R respectif (c.-à-d. le fichier .R qui contient la fonction qui génère l'erreur). Error in [.data.frame(x, i, j) : object 'Val' not found ).

  3. Type library(devtools) et définissez votre répertoire de travail pour pointer vers le répertoire principal de votre paquetage R.

  4. Type document() . Cela permettra de s'assurer que votre NAMESPACE comprend un fichier import(data.table) ligne.

  5. Type build()

  6. Type install()

Pour une bonne introduction à ce que build() et install() faire, voir : http://kbroman.org/pkg_primer/ .

Ensuite, une fois que vous aurez fermé votre session R et que vous vous serez connecté la prochaine fois, vous pourrez immédiatement vous lancer :

  1. Type library("my_R_package")

  2. Tapez le nom de votre fonction qui se trouve dans le fichier .R mentionné ci-dessus.

  3. Profitez-en ! Vous ne devriez plus recevoir le redoutable Error in [.data.frame(x, i, j) : object 'Val' not found

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X