views:

212

answers:

4

I'm trying to draw a smooth curve in R. I have the following simple toy data:

> x
 [1]  1  2  3  4  5  6  7  8  9 10
> y
 [1]  2  4  6  8  7 12 14 16 18 20

Now when I plot it with a standard command it looks bumpy and edgy, of course:

plot(x,y, type='l', lwd=2, col='red')

How can I make the curve smooth so that the 3 edges are rounded using estimated values? I know there are many methods to fit a smooth curve but I'm not sure which one would be most appropriate for this type of curve and how you would write it in R.

+6  A: 

I like loess() a lot for smoothing:

> x <- 1:10
> y <- c(2,4,6,8,7,12,14,16,18,20)
> lo <- loess(y~x)
> plot(x,y)
> lines(predict(lo), col='red', lwd=2)

Venables and Ripley's MASS book has an entire section on smoothing that also covers splines and polynomials -- but loess() is just about everybody's favourite.

Dirk Eddelbuettel
How do you apply it to this data? I'm not sure how because it expects a formula. Thanks!
As I showed you in the example when if `x` and `y` are visible variables. If they are columns of a data.frame named `foo`, the you add a `data=foo` option to the `loess(y ~ x. data=foo)` call -- just like in almost all other modeling functions in R.
Dirk Eddelbuettel
i also like `supsmu()` as an out-of-the-box smoother
apeescape
+1  A: 

LOESS is a very good approach, as Dirk said.

Another option is using Bezier splines, which may in some cases work better than LOESS if you don't have many data points.

Here you'll find an example: http://rosettacode.org/wiki/Cubic_bezier_curves#R

nico
+2  A: 

Maybe smooth.spline is an option, You can set a smoothing parameter (typically between 0 and 1) here

smoothingSpline = smooth.spline(x, y, spar=0.35)
plot(x,y)
lines(smoothingSpline)

you can also use predict on smooth.spline objects. The function comes with base R, see ?smooth.spline for details.

Karsten W.
+1  A: 

but to get it REALLY smoooth...

x <- 1:10
y <- c(2,4,6,8,7,8,14,16,18,20)
lo <- loess(y~x)
plot(x,y)
xl <- seq(min(x),max(x), (max(x) - min(x))/1000)
lines(xl, predict(lo,xl), col='red', lwd=2)

This style interpolates lots of extra points and gets you a more true loess curve that is very smooth.

John