2012-05-10 12 views
56

Sto cercando di usare il pacchetto data.table all'interno del mio proprio pacchetto. MWE è la seguente:Utilizzando pacchetto data.table dentro il mio pacchetto

Creo una funzione, test.fun, che crea semplicemente un piccolo oggetto data.table, quindi somma il raggruppamento di colonne "Val" per la colonna "A". Il codice è

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

Quando creo questa funzione in una normale sessione R e quindi eseguo la funzione, funziona come previsto.

> 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 

Quando ho messo questa funzione in un pacchetto, installare il pacchetto, caricare il pacchetto, e quindi eseguire la funzione, ricevo un messaggio di errore.

> 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 

Qualcuno può spiegarmi perché questo sta accadendo e cosa posso fare per risolverlo. Qualsiasi aiuto è molto apprezzato.

+11

La mia ipotesi è che non hai dichiarato una dipendenza. Dovresti rimuovere 'library (data.table)' dalla tua funzione e dichiarare 'depends: data.table' nel tuo namespace e DESCRIPTION. – Andrie

risposta

67

indovinare di Andrie è giusto, +1. C'è una FAQ su di esso (vedi vignette("datatable-faq")), così come una nuova vignette sull'importazione data.table:

FAQ 6.9: ho creato un pacchetto che dipende da data.table. Come faccio a assicurarmi che il mio pacchetto sia data.table-aware in modo che l'ereditarietà di data.frame funzioni?

In entrambi i) comportare data.table nel Depends: campo del vostro file di descrizione, o ii) includere data.table nel Imports: campo del file DESCRIZIONE E import(data.table) nel file NAMESPACE.

Ulteriori fondo ... in cima [.data.table (e di altre funzioni data.table), vedrete un interruttore in base al risultato di una chiamata a cedta(). Questo sta per Calling Environment Data Table Aware. Digitando data.table:::cedta rivela come è fatto. Si basa sul pacchetto chiamante che ha uno spazio dei nomi e, su tale spazio dei nomi Importing o Depending su data.table. Questo è il modo data.table può essere passato a non data.table-aware pacchetti (come funzioni in base) e quei pacchetti possono usare assolutamente di serie [.data.frame sintassi sulla data.table, beatamente ignaro che il data.frameis() un data.table, anche.

Questo è anche il motivo per cui l'ereditarietà di data.table non era compatibile con i pacchetti namespaceless e perché, su richiesta dell'utente, dovevamo chiedere agli autori di tali pacchetti di aggiungere uno spazio dei nomi al loro pacchetto per essere compatibili. Fortunatamente, ora che R aggiunge uno spazio dei nomi di default per i pacchetti mancanti uno (da v2.14.0), che il problema è andato via:

CAMBIAMENTI R VERSIONE 2.14.0
* Tutti i pacchetti devono avere uno spazio dei nomi, e uno viene creato all'installazione se non è fornito nelle fonti.

+4

+1 Ottima risposta. – Andrie

+0

(Mi dispiace far rivivere questo, ma ...) Matthew, puoi chiarire come funzionerebbe da un punto di vista interattivo? Se il mio pacchetto restituisce un 'data.table' a un utente in una sessione interattiva, sarà loro richiesto di usare la semantica' data.table', o c'è un modo in cui potrei supportare la consueta sintassi 'data.frame'? –

+1

@JeffAllen Questo è nuovo ... non sono sicuro. Se il tuo pacchetto dipende da data.table allora questo renderà consapevole l'utente data.table. Forse importando data.table non lo farebbe (e forse è quello che vorresti). –

14

Ecco la ricetta completa:

1) Aggiungere data.table al Imports nel file DESCRIPTION.

2) Aggiungere @import data.table al proprio file .R (ad esempio, il file .R che contiene la propria funzione che genera l'errore Error in [.data.frame(x, i, j) : object 'Val' not found).

3) Digitare library(devtools) e impostare la directory di lavoro in modo che punti alla directory principale del pacchetto R.

4) Tipo document(). Ciò garantirà che il tuo file NAMESPACE includa una riga import(data.table).

5) Type build()

6) Type install()

Per una bella primer su ciò che build() e install() fare, vedere: http://kbroman.org/pkg_primer/.

Poi, una volta che si chiude la sessione di R e login la prossima volta, si può immediatamente saltare a destra con:

1) Tipo library("my_R_package")

2) Digitare il nome della funzione che è ospitato nel. File R sopra menzionato.

3) Buon divertimento! Non dovresti più ricevere il temuto Error in [.data.frame(x, i, j) : object 'Val' not found

+2

il comando '@import data.table' è particolarmente utile – mbarete

Problemi correlati