2016-04-13 14 views
1

Ich bin ein Paket baut das wird:Umfang NLS Selbststart-Funktionen

  1. in einem Datenlese gesetzt
  2. bestimmen, welche Komponenten sind erforderlich, um die Daten zu modellieren
  3. eine selbst bauen NLS Modell diejenigen Komponenten
  4. unter Verwendung von Ausgangs anwenden, das Modell zu den Daten

Das Ergebnis ist sto rot in einer Liste, die die Daten, das Modell und das Ergebnis von nls enthält. Alles funktioniert bis Schritt 4. Ich habe meine konstruierten Modelle in der Liste gespeichert, und R erkennt sie nicht mehr als selfStart-Funktionen.

Hier ist ein Spielzeugbeispiel, das mein Problem veranschaulicht. Die folgende Funktion (vom SSlogis manuell) funktioniert auf der obersten Ebene:

Chick.1 <- ChickWeight[ChickWeight$Chick == 1, ] 
fm1 <- nls(weight ~ SSlogis(Time, Asym, xmid, scal), data = Chick.1) 
fm1 

Nonlinear Regressionsmodell
Modell: Gewicht ~ SSlogis (Zeit, Asym, xmid, skal) Daten: Chick.1
Asym xmid SCAL
937,02 35,22 11,41
Restsumme der Quadrate: 76.66

Anzahl von Iterationen für die Konvergenz: 0
Erreicht Konvergenztoleranz: 7.778e-07

Aber wenn ich die Funktion und die Daten zusammen in einer Liste speichern, ist R nicht die selbststartenden Funktion als selbststart mehr sehen:

myobj <- list() 
myobj$model <- SSlogis 
myobj$data <- ChickWeight[ChickWeight$Chick == 1, ] 

nls(weight ~ myobj$model(Time, Asym, xmid, scal), data = myobj$data) 

Fehler in getInitial.default (func, Daten, McAll = as.list (match.call (func,:
no 'getInitial' Methode "Funktion" gefundenen Objekte

Mein Workflow wird schließlich die Verarbeitung von Dutzenden von Datensätzen umfassen. Daher möchte ich jeden Datensatz und das zugehörige Modell in einem eigenen Objekt behalten (und diese Objekte werden wahrscheinlich in einer Liste von Objekten landen). Gibt es eine Möglichkeit, die Umgebung meiner SelfStart-Funktionen beizubehalten oder wiederherzustellen, auch wenn sie in einer anderen Liste gespeichert sind?

UPDATE

Als Reaktion auf Gregor Vorschlag, habe ich versucht, dies:

nls(as.formula(sprintf("weight ~ %s(Time, Asym, xmid, scal)", 
         "myobj$model")), data = myobj$data) 

Fehler in nls (as.formula (sprintf ("Gewicht ~% s (Zeit, Asym, xmid, scal)“:
Singular Steigung Zusätzlich: Warnmeldung:
In nls (as.formula (sprintf ("Gewicht ~% s (Zeit, Asym, xmid, skal)":
keine Startwerte specifie d für einige Parameter.
"Asym", "xmid", "scal" auf "1." initialisieren.
Betrachten Sie 'Start' Angabe oder ein Selbststart Modell

Update 2

Inspiriert von @Gregor mit I mit einer Vermeidung des Problems kam:

nlsDispatch <- function(obj){ 
    GLOBAL_NLS <<- obj$model 
    nls(weight ~ GLOBAL_NLS(Time, Asym, xmid, scal), data = myobj$data) 
} 

nlsDispatch(myobj) 


Modell Nonlinear Regressionsmodell : Gewicht ~ GLOBAL_NLS (Zeit, Asym, xmid, scal)
Daten: myobj $ Daten
Asym xmid scal
937,02 35,22 11,41
Restsumme der Quadrate: 76.66

Anzahl der Iterationen für die Konvergenz: 0
Erreicht Konvergenztoleranz: 6.621e-07

Das funktioniert, aber Meine Funktion in die globale Umgebung fallen zu lassen ist hässlich. Und es deutet darauf hin, dass ich in der Lage sein sollte, die globale Umgebung zu missbrauchen, um dies zu erreichen, wenn ich Umgebungen besser handhaben könnte.

: In meiner Anwendung ist diese meist eine Frage Spitzen zu zählen, und herauszufinden, wie viele normale Kurven nötig sind, um sie zu modellieren.

+0

Sie behandeln die rechte Seite einer Formel, als ob es ein Argument ist ... aber es ist nicht.Es mag einen besseren Weg geben, aber ich würde vorschlagen, Ihre Formel als String 'sprintf (" Gewicht ~% s (Zeit, Asym, xmid, scal) "," SSlogis ") zu konstruieren und dann' as.formula() zu verwenden. 'darauf. – Gregor

+0

@Gregor danke - Ich habe das versucht und einen etwas anderen Fehler bekommen. Beachten Sie, dass ich "myobj $ model" anstelle von "SSlogis" verwendet habe. 'SSlogis' funktioniert so wie es ist. – Tyler

+0

Ich würde denken, meine Version würde so funktionieren: 'sprintf (" Gewicht ~% s (Zeit, Asym, xmid, scal) ", myobj $ Modell)' wenn 'myobj $ model' einen String-Namen der Funktion hat statt das eigentliche Funktionsobjekt. – Gregor

Antwort

2

1) Dies funktioniert:

Model <- myobj$model 
nls(weight ~ Model(Time, Asym, xmid, scal), data = myobj$data) 

geben
Nonlinear regression model 
    model: weight ~ Model(Time, Asym, xmid, scal) 
    data: myobj$data 
    Asym xmid scal 
937.02 35.22 11.41 
residual sum-of-squares: 76.66 

Number of iterations to convergence: 0 
Achieved convergence tolerance: 6.621e-07 

2) Es Scoping scheint für Selbststartfunktionen durcheinander. Das Problem scheint in getInitial.formula, die diese Zeile verwendet:

func <- get(as.character(object[[2L]][[1L]])) 

Beachten Sie, dass es zu get (Umwelt) kein zweites Argument ist, damit es nicht die Aufmerksamkeit auf Umgebungen zahlen.

Wenn Sie also die Lösung oben in Funktion setzen wollen es dann müssen Sie um es so arbeiten:

f <- function() { 
    myobj <- list() 
    myobj$model <- SSlogis 
    myobj$data <- ChickWeight[ChickWeight$Chick == 1, ] 
    Model <<- myobj$model 
    nls(weight ~ Model(Time, Asym, xmid, scal), data = myobj$data) 
} 
f() 

3) Ein weiteres workaound Modell zu befestigen ist. Das würde es aus dem globalen Arbeitsbereich heraushalten. Beachten Sie, dass wir es anschließend abtrennen, damit die Funktion keine Spuren hinterlässt.

f2 <- function() { 
    on.exit(detach()) 
    if (any(grepl("list", search()))) stop("list already on search path") 
    myobj <- list() 
    myobj$model <- SSlogis 
    myobj$data <- ChickWeight[ChickWeight$Chick == 1, ] 
    attach(list(Model = myobj$model)) 
    nls(weight ~ Model(Time, Asym, xmid, scal), data = myobj$data) 
} 
f2() 

Beachten Sie, dass, wenn die detach dann nicht auftreten, das nächste Mal, wenn ein attach dort getan wird, um zwei Punkte auf der Suchliste angebracht wäre (während im Stand der Ansatz überschreibt es immer die globale Variable, so dass nicht kann passieren), also überprüfen wir, dass es keine solche Liste auf dem Suchpfad gibt, und stoppen mit einem Fehler, falls vorhanden.

+0

Danke für die Erklärung! – Tyler

+0

Habe eine weitere Problemumgehung hinzugefügt. –

+0

Das ist sauberer, danke! – Tyler