Die anderen Antworten sind alle gute Ansätze. Es gibt jedoch einige andere Optionen in R, die nicht erwähnt wurden, einschließlich lowessund approx, die möglicherweise eine bessere Passform oder eine schnellere Leistung ergeben.
Die Vorteile lassen sich mit einem alternativen Datensatz leichter demonstrieren:
sigmoid <- function(x)
{
y<-1/(1+exp(-.15*(x-100)))
return(y)
}
dat<-data.frame(x=rnorm(5000)*30+100)
dat$y<-as.numeric(as.logical(round(sigmoid(dat$x)+rnorm(5000)*.3,0)))
Hier sind die Daten, die mit der Sigmoidkurve überlagert sind, die sie generiert hat:

Diese Art von Daten ist häufig, wenn ein binäres Verhalten in einer Population betrachtet wird. Dies kann beispielsweise ein Diagramm darüber sein, ob ein Kunde etwas gekauft hat (ein binäres 1/0 auf der y-Achse) oder nicht, und wie viel Zeit er auf der Site verbracht hat (x-Achse).
Eine große Anzahl von Punkten wird verwendet, um die Leistungsunterschiede dieser Funktionen besser zu demonstrieren.
Smooth, splineUndsmooth.spline alle Produkte Kauderwelsch auf einem Datensatz , wie dies mit jedem Satz von Parametern habe ich versucht, vielleicht aufgrund ihrer Neigung zu jedem Punkt auf der Karte, die für verrauschte Daten nicht funktioniert.
Die loess, lowessund approxFunktionen alle Produkte brauchbare Ergebnisse, wenn auch nur knapp für approx. Dies ist der Code für jeden, der leicht optimierte Parameter verwendet:
loessFit <- loess(y~x, dat, span = 0.6)
loessFit <- data.frame(x=loessFit$x,y=loessFit$fitted)
loessFit <- loessFit[order(loessFit$x),]
approxFit <- approx(dat,n = 15)
lowessFit <-data.frame(lowess(dat,f = .6,iter=1))
Und die Ergebnisse:
plot(dat,col='gray')
curve(sigmoid,0,200,add=TRUE,col='blue',)
lines(lowessFit,col='red')
lines(loessFit,col='green')
lines(approxFit,col='purple')
legend(150,.6,
legend=c("Sigmoid","Loess","Lowess",'Approx'),
lty=c(1,1),
lwd=c(2.5,2.5),col=c("blue","green","red","purple"))

Wie Sie sehen können, lowessergibt sich eine nahezu perfekte Anpassung an die ursprüngliche Erzeugungskurve. Loessist nah, erfährt aber eine merkwürdige Abweichung an beiden Schwänzen.
Obwohl Ihr Datensatz sehr unterschiedlich sein wird, habe ich festgestellt, dass andere Datensätze ähnlich funktionieren, mit beiden loessund lowessin der Lage sind, gute Ergebnisse zu erzielen. Die Unterschiede werden bedeutender, wenn Sie sich Benchmarks ansehen:
> microbenchmark::microbenchmark(loess(y~x, dat, span = 0.6),approx(dat,n = 20),lowess(dat,f = .6,iter=1),times=20)
Unit: milliseconds
expr min lq mean median uq max neval cld
loess(y ~ x, dat, span = 0.6) 153.034810 154.450750 156.794257 156.004357 159.23183 163.117746 20 c
approx(dat, n = 20) 1.297685 1.346773 1.689133 1.441823 1.86018 4.281735 20 a
lowess(dat, f = 0.6, iter = 1) 9.637583 10.085613 11.270911 11.350722 12.33046 12.495343 20 b
Loessist extrem langsam und dauert 100x so lange wie approx. Lowessliefert bessere Ergebnisse als approx, läuft aber immer noch ziemlich schnell (15x schneller als Löss).
Loess Mit zunehmender Anzahl von Punkten bleibt es auch zunehmend stecken und wird um 50.000 unbrauchbar.
BEARBEITEN: Zusätzliche Untersuchungen zeigen, dass loessbestimmte Datensätze besser passen. Wenn Sie mit einem kleinen Datensatz arbeiten oder die Leistung keine Rolle spielt, probieren Sie beide Funktionen aus und vergleichen Sie die Ergebnisse.