2011-01-10 7 views
7

Ich muss einige simulierte Daten glätten, aber gelegentlich Probleme auftreten, wenn die simulierten zu glättenden Ordinaten meistens den gleichen Wert haben. Hier ist ein kleines reproduzierbares Beispiel für den einfachsten Fall.Fehler mit `Löss.Smooth` aber nicht` Löss` oder `Lowess`

> x <- 0:50 
> y <- rep(0,51) 
> loess.smooth(x,y) 
Error in simpleLoess(y, x, w, span, degree, FALSE, FALSE, normalize = FALSE, : 
    NA/NaN/Inf in foreign function call (arg 1) 

loess(y~x), lowess(x,y) und ihre analogen in MATLAB in diesem Beispiel die erwarteten Ergebnisse ohne Fehler. Ich benutze loess.smooth hier, weil ich die Schätzungen an einer bestimmten Anzahl von Punkten ausgewertet benötigt. Laut der Dokumentation, glaube ich, loess.smooth und loess verwenden die gleichen Schätzfunktionen, aber ersteres ist eine "Hilfsfunktion", um die Bewertungspunkte zu behandeln. Der Fehler scheint aus einer C-Funktion zu kommen:

> traceback() 
3: .C(R_loess_raw, as.double(pseudovalues), as.double(x), as.double(weights), 
    as.double(weights), as.integer(D), as.integer(N), as.double(span), 
    as.integer(degree), as.integer(nonparametric), as.integer(order.drop.sqr), 
    as.integer(sum.drop.sqr), as.double(span * cell), as.character(surf.stat), 
    temp = double(N), parameter = integer(7), a = integer(max.kd), 
    xi = double(max.kd), vert = double(2 * D), vval = double((D + 
     1) * max.kd), diagonal = double(N), trL = double(1), 
    delta1 = double(1), delta2 = double(1), as.integer(0L)) 
2: simpleLoess(y, x, w, span, degree, FALSE, FALSE, normalize = FALSE, 
    "none", "interpolate", control$cell, iterations, control$trace.hat) 
1: loess.smooth(x, y) 

loess auch nennt simpleLoess, aber mit dem, was erscheint unterschiedliche Argumente zu sein. Natürlich, wenn Sie genug von den y-Werten auf ungleich Null ändern, läuft loess.smooth ohne Fehler, aber ich brauche das Programm, um sogar im extremsten Fall zu laufen.

Hoffentlich kann mir jemand helfen mit einer und/oder alle der folgenden Optionen:

  1. verstehen, warum nur loess.smooth, und nicht die anderen Funktionen, erzeugt diesen Fehler und eine Lösung für dieses Problem zu finden.
  2. Finden Sie einen Workaround mit loess, aber immer noch die Schätzung an einer angegebenen Anzahl von Punkten, die sich von dem Vektor x unterscheiden können. Zum Beispiel möchte ich vielleicht nur x <- seq(0,50,10) in der Glättung verwenden, aber die Schätzung unter x <- 0:50 auswerten. Soweit ich weiß, wird die Verwendung von predict mit einem neuen Datenrahmen diese Situation nicht richtig behandeln, aber lassen Sie mich bitte wissen, wenn ich etwas vermisse.
  3. Behandeln Sie den Fehler auf eine Weise, die das Programm nicht daran hindert, auf den nächsten simulierten Datensatz zu wechseln.

Vielen Dank im Voraus für jede Hilfe zu diesem Problem.

Antwort

7

Für Teil 1: Dies dauerte etwas aufzuspüren, aber wenn Sie tun :

loess.smooth(x, y, family = "guassian")

das Modell passt. Dies ergibt sich aufgrund der unterschiedlichen Voreinstellungen von loess.smooth und loess; das ehemalige hat family = c("symmetric", "gaussian"), während das letztere es umgekehrt hat. Wenn Sie den Code für loess und loess.smooth durchforsten, sehen Sie, dass family = "gaussian"iterations auf 1 eingestellt ist. Andernfalls wird der Wert loess.control()$iterations angenommen.Wenn Sie Iterationen in simpleLoess tun, gibt den folgenden Funktionsaufruf einen Vektor von NaN:

pseudovalues <- .Fortran(R_lowesp, as.integer(N), as.double(y), 
      as.double(z$fitted.values), as.double(weights), as.double(robust), 
      integer(N), pseudovalues = double(N))$pseudovalues 

, die den nächsten Funktionsaufruf bewirkt, um den Fehler werfen Sie sahen:

zz <- .C(R_loess_raw, as.double(pseudovalues), as.double(x), 
      as.double(weights), as.double(weights), as.integer(D), 
      as.integer(N), as.double(span), as.integer(degree), 
      as.integer(nonparametric), as.integer(order.drop.sqr), 
      as.integer(sum.drop.sqr), as.double(span * cell), 
      as.character(surf.stat), temp = double(N), parameter = integer(7), 
      a = integer(max.kd), xi = double(max.kd), vert = double(2 * 
       D), vval = double((D + 1) * max.kd), diagonal = double(N), 
      trL = double(1), delta1 = double(1), delta2 = double(1), 
      as.integer(0L)) 

Das alles robuste Armatur bezieht in Löss (die Methode). Wenn Sie keine robuste Anpassung wünschen/benötigen, verwenden Sie family = "gaussian" in Ihrem loess.smooth Aufruf.

Beachten Sie auch, dass die Standardeinstellungen für von denen von loess abweichen, z. für 'span' und 'degree'. Überprüfen Sie also sorgfältig, welche Modelle Sie anpassen möchten, und passen Sie die Standardeinstellungen der jeweiligen Funktion an.

Für Teil 2:

DF <- data.frame(x = 0:50, y = rep(0,51)) 
mod <- loess(y ~ x, data = DF) 
pred <- predict(mod, newdata = data.frame(x = c(-1, 10, 15, 55))) 
mod2 <- loess(y ~ x, data = DF, control = loess.control(surface = "direct")) 
pred2 <- predict(mod2, newdata = data.frame(x = c(-1, 10, 15, 55))) 

Welche gibt:

> pred 
1 2 3 4 
NA 0 0 NA 
> pred2 
1 2 3 4 
0 0 0 0 

Der Standard wird nicht extrapolieren, wenn das ist, was Sie meinen. Ich sehe nicht, was das Problem mit der Verwendung von predict hier überhaupt ist.

Für Teil 3: Blick auf ?try und ?tryCatch, die Sie rund um die Löss FitFunktion wickeln kann (loess.smooth sagen), die Berechnungen, wenn ein Fehler in loess.smooth fortsetzen können angetroffen wird.

Sie müssen die Ausgabe von try oder tryCatch, indem so etwas wie (zu handhaben, wenn Sie dies in einer Schleife tun:

mod <- try(loess.smooth(x, y)) 
if(inherits(mod, "try-error")) 
    next 
## if here, model work, do something with `mod` 

ich wahrscheinlich try oder tryCatch mit Beschlag über loess verbinden würde und mit predict für solch ein Problem.

+0

löschte meine Antwort, wie das selbe, das Sie jetzt bekannt gaben. –

+0

@Joris - keine Notwendigkeit, es gelöscht zu haben. Ich war im Begriff, Ihre Antwort zu verbessern! –

+0

Ich habe etwas auf Teil 1 von t hinzugefügt Die Frage des OP, warum 'loess.smooth' mit der dargestellten Problematik scheitert. –

0

Dies ist das erste Mal, dass ich auf diese Funktionen stoße, also kann ich Ihnen nicht so viel helfen, aber kann das nicht etwas mit einer Varianz von 0 in den y-Werten zu tun haben? Nun versuchen Sie eine glatte Linie von Daten zu schätzen, die bereits so glatt wie es geht, und dies funktioniert:

x <- 0:50 
y <- c(rep(0,25),rep(1,26)) 
loess.smooth(x,y) 
Verwandte Themen