2016-08-10 5 views
1

Mein Ziel ist es, eine Funktion zu haben, die:Wie übergebe ich "..." an eine neue Umgebung in R?

  • auf eine Funktion arbeitet und gibt eine Funktion
  • Die Rückkehr Funktion mit .GlobalEnv als Eltern und
  • eine neue Umgebung erzeugt
  • wertet die Argumentfunktion in der neuen Umgebung aus.

Es wäre so etwas wie dies funktioniert:

# Create an object that doesn't exist in the new.env 
iris2 <- iris 
model <- in_new_env(lm)(Sepal.Length ~ Sepal.Width, iris2) 

Der Grund, warum ich dies tun wollen ist, dass ich oft Anwendungen, bei denen ich ein Modell/ggplot innerhalb einer Funktion generieren möchten, dass große Elemente enthält, die werden nicht direkt im Modell/ggplot-Aufruf verwendet. Da diese Objekte ihre rufende Umgebung mit sich herumtragen, sind die Objekte beim Speichern sehr groß oder werden von einem parallelen Cluster zurückbewegt.

Mein Startversuch ist:

in_new_env <- function(.f){ 
    function(...) { 
    env <- new.env(parent = globalenv()) 
    # This doesn't seem to actually export the ... to env 
    assign("...", ..., envir = env) 
    env$.f <- .f 
    with(env, .f(...)) 
    # Error in eval(expr, envir, enclos) : '...' used in an incorrect context 
    } 
} 

Dies funktionieren würde, wenn ich in der Lage war, die ... zu env exportieren. Wie mache ich das? Ist es möglich? Haben Sie Vorschläge für eine alternative Strategie für in_new_env?

Dies wäre dann ein praktischer Wrapper für die von Bill Dunlap here vorgeschlagene Lösung.

+0

Vielleicht möchten Sie sich das kürzlich angekündigte 'ggghost'-Paket ansehen, das seine Aufgabe scheinbar so ausführt (zumindest so, wie ich es verstehe) für ggplot2-Funktionsketten. (Ich habe keine Erfahrung damit.) Ich denke speziell, dass 'summary.ggghost', beschrieben als" Liste der in einem ggghost-Objekt enthaltenen Aufrufe ", die Anforderungen erfüllen könnte. –

Antwort

4

Die ... ist wirklich keine Variable selbst, so dass Sie nicht wirklich zuweisen können. Wenn ich denke, dass ich verstehe, was Sie versuchen, können Sie etwas wie list(...) verwenden, um alle an eine Funktion übergebenen Parameter auszuwerten und sie in einer Liste zu speichern. Dann können Sie do.call() verwenden, um diese Liste der Parameter an eine andere Funktion zu übergeben und diese in einer anderen Umgebung mit evalq auszuwerten. Ich denke, das tut, was Sie wollen ...

in_new_env <- function(.f){ 
    function(...) { 
    params <- list(...) 
    env <- new.env(parent = globalenv()) 
    assign(".params.", params, envir = env) 
    env$.f <- .f 
    evalq(do.call(".f", .params.), envir=env) 

    } 
} 

iris2 <- iris 
model <- in_new_env(lm)(Sepal.Length ~ Sepal.Width, iris2) 

Natürlich auf das Objekt der Anruf aus etwas ist, dass es die .f Funktion Name erinnert, aber es war mir nicht klar, was für, dass Ihr Plan war mit Ihrer vorgeschlagenen Funktion.

+0

Ich denke du meintest zu sagen, dass '" ... "' ist nicht der 'Name' von' ... ' –

+0

Dies beantwortet sicherlich meine Frage. Vielen Dank! Leider löst das mein Problem nicht. Ich bekomme immer noch das Problem, dass das Formelobjekt 'Sepal.Length ~ Sepal.Width'' die unnötigen Teile der Funktionsumgebung herumträgt. – kennyB

+0

@ 42- Nun, ich denke, mein Punkt war, dass es keine Möglichkeit gibt, "..." zuzuweisen und es in einer Funktion "arbeiten" zu lassen. Das Symbol '...' hat einen speziellen Modus, so dass es sich nicht wirklich wie eine "normale" Variable verhält. Ich wäre neugierig, wenn Sie ein Beispiel haben, wo es ist. – MrFlick

Verwandte Themen