2014-11-17 10 views
9

Attualmente sto sviluppando un plug-in per la GUI di R-Commander. In questo pacchetto sto usando una grande quantità di altri pacchetti che ho semplicemente allegato usando l'opzione Depends nel file di descrizione. Tuttavia ora sto passando all'opzione Imports e sto riscontrando alcuni problemi con esso. Perché voglio usare alcune funzioni non solo internamente nel mio codice, ma anche essere in grado di stamparle e usarle nella finestra di script di R Commander, dovrò anche esportarle nello spazio dei nomi.Importazione/esportazione di pacchetti utilizzando NAMESPACE

Prendiamo ad esempio il pacchetto biclust. Questo pacchetto ha le seguenti esportazioni nel suo spazio dei nomi:

# First a bunch of functions are exported (Note that the biclust function is not in here!) 
export(drawHeatmap,drawHeatmap2,bubbleplot,...,heatmapBC) 

# The classes are exported 
exportClasses(BiclustMethod,Biclust,BCBimax,BCCC,BCXmotifs,BCSpectral,BCPlaid) 

# Methods are exported 
exportMethods(biclust,show,summary) 

Così, quando mi library(biclust) in una sessione di R, funziona come previsto, il che significa che posso utilizzare il metodo di biclust/funzione nella console R.

Ora questo come il mio file namespace assomiglia (o almeno la parte di essa relative a questa discussione)

# I select those functions I need and import them. 
importFrom(biclust, drawHeatmap,...,biclustbarchart) 

# I import all the classes 
importClassesFrom(biclust,BiclustMethod,Biclust,BCBimax,BCCC,BCXmotifs,BCSpectral,BCPlaid) 

# I import all the methods 
importMethodsFrom(biclust,show,summary,biclust) 

# I now export all of the previous again so I can use the doItAndPrint functionality in R Commander 
export(drawHeatmap,...,biclustbarchart) 
exportClasses(BiclustMethod,Biclust,BCBimax,BCCC,BCXmotifs,BCSpectral,BCPlaid) 
exportMethods(biclust,show,summary) 

Tuttavia quando carico nel mio pacchetto di oggi, non funziona come previsto. Mentre le funzioni come drawHeatmap stanno lavorando, il biclust metodo/funzione non può essere trovato. (Anche se ho chiaramente importato ed esportato il metodo.)

Apparentemente l'unico modo per ottenere questo lavoro, è quello di mettere anche il metodo biclust nel normale comando export().

export(biclust,drawHeatmap,...,biclustbarchart) 

Qualcuno potrebbe chiarire cosa sto facendo male o cosa sta succedendo qui? Perché le stesse esportazioni funzionano per il pacchetto biclust, ma non per il mio pacchetto?

+2

Benvenuti in StackOverflow. Questa è una domanda ben formulata, ma non molto correlata a RCommander, quindi ho modificato il titolo in modo un po 'più generico. – Andrie

+0

I metodi 'show' e' summary'' S3' non sono? Qualcosa cambia se provi 'S3method (show, biclust)' nel tuo file 'NAMESPACE'? – nicola

+0

Non appena ho provato, il mio pacchetto non riuscirà a costruire. * Attenzione: il metodo S3 'biclust' è stato dichiarato in NAMESPACE ma non è stato trovato * – Ewoud

risposta

7

L'unica descrizione del tuo errore è che "non funziona come previsto", quindi il seguente è un piccolo accenno al buio.

È utile distinguere tra metodi e generici a cui sono associati. Biclust rende disponibili entrambi e sono strettamente associati. importFrom(biclust, biclust) importa i metodi generici e associati, importMethodsFrom(biclust, biclust) importa i metodi biclust definiti nel pacchetto biclust e implicitamente i generici su cui sono definiti i metodi. Questi sono funzionalmente equivalenti finora; Penso che l'intenzione originale di importMethodsFrom() fosse quando pkgA definisce un generico, pkgB definisce i metodi sul generico, e pkgD vuole usare il generico da pkgA ei metodi su quello generico definito in pkgA e pkgB - import (pkgA, foo), importMethodsFrom (pkgB, foo).

All'altra estremità, quando si dice exportMethods(foo), si richiede a R di rendere i metodi foo definiti nel pacchetto disponibili per altri utenti. Ma non ci sono metodi foo definiti nel pacchetto, quindi non viene esportato nulla (forse questo dovrebbe generare un errore, oppure i metodi che si importano dovrebbero essere esportati di nuovo). D'altra parte, export(foo) dice a R di esportare il foo generico, che è disponibile per l'esportazione: è il simbolo che hai importato in precedenza. (Si dice che "metti il ​​metodo biclust anche nel normale export()", ma in realtà è generico (e tutti i metodi ad esso associati) disponibili per l'esportazione.) Quindi esportare biclust, piuttosto che i metodi definiti su di esso, sembra essere ciò che vuoi fare

In genere, direi che importare e quindi riesportare funzioni o generici definiti in altri pacchetti non è la cosa giusta da fare - biclust, non il pacchetto, fornisce e documenta il generico, e biclust probabilmente dovrebbe appartenere a Dipende: - presumibilmente, molte altre funzioni di biclust vengono generalmente utilizzate insieme al generico. Forse la tua GUI Rcommander è un'eccezione.

Anche se Imports: implica lavoro aggiuntivo (nel file NAMESPACE), è solitamente il caso che i pacchetti appartengano a Imports: piuttosto che Depends: - rende il codice nel pacchetto molto più robusto (vengono trovate funzioni importate nello spazio del nome del pacchetto, piuttosto che nel percorso di ricerca che l'utente può facilmente modificare) e riduce la probabilità che l'utente incontri scontri di nomi tra simboli identici definiti in pacchetti diversi.

+0

Grazie per la spiegazione di chiarimento! Normalmente vorrei semplicemente continuare a utilizzare Depends poiché tutti questi problemi di importazione/esportazione non si verificano semplicemente. Comunque il pacchetto che si sta sviluppando (una GUI per il biclustering), sta facendo molti pacchetti di biclustering che a volte usano gli stessi nomi per le funzioni. Pertanto alcune importazioni selettive sono diventate necessarie. La necessità di esportare la funzione è la seguente. R-Commander ha una funzione molto bella che il tuo codice R viene generato mentre fai clic sulle finestre di dialogo. (segue) – Ewoud

+0

(segue) Quello che sta realmente accadendo è che facendo clic sui pulsanti nella GUI, il codice R viene stampato nella finestra di script di R Commander che viene quindi eseguita nella console R. Quindi se voglio stampare/eseguire funzioni importate da altri pacchetti, in realtà ho anche bisogno di esportarli perché altrimenti non saranno trovati nella R Console (che ovviamente se non accade quando si usa dipende). Se avessi bisogno solo delle funzioni importate internamente nelle mie funzioni, penso che l'esportazione non sarebbe stata necessaria, ma ora lo è. – Ewoud