2013-01-13 12 views
9

Meine letzte Einreichung bei CRAN wurde zurückgeworfen, weil ich Aufgaben in der globalen Umgebung habe, die jetzt verpönt ist.Aktualisieren von eingebetteten Daten, zum Beispiel sysdata.rda

Ich habe eine eingebettete Datei (sysdata.rda), die Konfigurationsparameter basierend auf dem Status (wie in den USA) der Benutzer enthält. Ich wollte, dass dieser eingebettete Datensatz aktualisierbar ist, wenn ein neuer Benutzer das Programm verwendet. Ich habe diese Daten in der Anfangsfunktion, die der Benutzer verwendet, zuvor aktualisiert und dem Benutzer über die globale Zuordnung zugänglich gemacht.

Ich habe Mühe herauszufinden, wie diese eingebetteten Daten aktualisiert werden und sie zu den Standarddaten machen, die der Benutzer für den Rest der Sitzung verwendet.

Zuvor hatte ich die Daten in/data untergebracht und kürzlich auf /R/sysdata.rda umgestellt, da es für dieses Gebietsschema besser geeignet schien. Jetzt bin ich mir nicht so sicher.

Jede Hilfe sehr geschätzt

+0

Möchten Sie nach der Installation im Paket einmal oder nach jedem Laden des Pakets fragen, in welchem ​​Zustand? – hadley

+0

Sie laden das Paket mit ihren gelieferten Daten und zeigen an, aus welchem ​​Zustand sie stammen (z. B. TX). Das Paket erkennt, dass seine zustandsspezifischen Parameter nicht Teil der eingebetteten Daten sind, berechnet sie so gut wie möglich und fügt sie dann dem eingebetteten Dataset hinzu. Das Problem, das ich habe, ist dann, diesen aktualisierten Datensatz während des Rests der Sitzung zur Verfügung zu stellen. Ich habe es getan, indem ich es .GlobalEnv zugewiesen habe. – dbetebenner

Antwort

4

Der Schlüssel besteht darin, die Zuweisung in einer anderen Umgebung als der globalen Umgebung vorzunehmen. Es gibt zwei grundlegende Techniken, mit local() und <<- oder explizit eine neue Umgebung zu schaffen:

mit einer expliziten Umgebung zu arbeiten, ist einfach: die Umwelt schaffen und weisen in sie wie eine Liste:

my_opts <- new.env(parent = emptyenv()) 
set_state <- function(value) my_opts$state <- value 
get_state <- function() my_opts$state 

Mit local() ist ein wenig komplexer, und ein paar Tricks mit <<-

set_state <- NULL 
get_state <- NULL 

local({ 
    state <- NULL 
    get_state <<- function() state 
    set_state <<- function(value) state <<- value 
}) 

Für weitere Informationen benötigt, wie <<- Werkesehen, im Abschnitt "Zuordnung: Namen an Werte binden".

+0

Sehr hilfreich! Ich bin die erste Route gegangen. Wenn die Funktion die Daten des Status nicht findet, erstellt sie eine Umgebung und füllt die Verzweigung dieses Status in die eingebetteten Daten (eine große Liste mit einer Verzweigung für jeden Status). Die aktualisierten Daten werden dann der neuen Umgebung zugewiesen.Ich stoße jetzt auf R CMD-Check - As-Cran für die Verwendung von "attach", so dass die aktualisierten Daten nach dem Beenden der Funktion verwendet wird. Ich bin nicht sicher, wie man das umgehen kann. – dbetebenner

+0

Anstatt "attach" zu verwenden, schreiben Sie einfach eine Funktion, die auf die gewünschten Daten zugreift, und rufen Sie diese im gesamten Code auf. – hadley

+0

Hmmm. Ich muss etwas verpassen. Die Daten (nennen wir es "interne_Daten") werden in einem Aufruf einer Funktion erweitert. Ich bin mir nicht sicher, wie man 'interne_data' aus dieser Funktion herausholen kann (ich möchte sie nicht als Teil dessen zurückgeben, was die Funktion zurückgibt, da dies nicht der Sinn der Funktion ist). Die Lösung meines derzeitigen armen Mannes (der R CMD-Kontrolle - as-crane besteht, ist, das Objekt zu speichern und dann in das .GlobalEnv zu laden. – dbetebenner

1

Warum nicht eine foo.R Datei in /data haben, die die Daten und aktualisiert sie geladen wird, wenn der Benutzer data(foo) ruft? Dies ist eine der zulässigen Optionen für /data, aber beachten Sie die folgenden von Writing R Extensions

Beachten Sie, dass Code R sein sollte „autark“ und nicht die Verwendung zusätzlicher Funktionalität, die von dem Paket zur Verfügung gestellt machen, so dass die Datendatei kann auch verwendet werden, ohne das Paket zu laden.

Wenn Sie mit dieser Einschränkung leben können dann data(foo) könnten die Daten laden, aktualisieren und sicherzustellen, dass sie in einem bestimmten benannte Objekt ist, die Sie dann in Ihren Funktionen beziehen sich auf.

+0

Hatte keine * .R-Datei in/data berücksichtigt. Ich gebe das eine Drehung – dbetebenner

Verwandte Themen