Я пытаюсь нарисовать плавную кривую в R
. У меня есть следующие простые данные игрушки:
> x
[1] 1 2 3 4 5 6 7 8 9 10
> y
[1] 2 4 6 8 7 12 14 16 18 20
Теперь, когда я строю их с помощью стандартной команды, она, конечно, выглядит неровной и резкой:
> plot(x,y, type='l', lwd=2, col='red')
Как я могу сделать кривую гладкой, чтобы 3 ребра были округлены с использованием оценочных значений? Я знаю, что существует много методов для подгонки гладкой кривой, но я не уверен, какой из них будет наиболее подходящим для этого типа кривой, и как бы вы написали его в R
.
Мне очень нравится loess ()
для сглаживания:
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)
В книге MASS Венейбла и Рипли есть целый раздел о сглаживании, который также охватывает сплайны и полиномы, но loess ()
почти всем нравится.
Возможно, это опция smooth.spline. Здесь вы можете установить параметр сглаживания (обычно от 0 до 1)
smoothingSpline = smooth.spline(x, y, spar=0.35)
plot(x,y)
lines(smoothingSpline)
вы также можете использовать прогноз для объектов smooth.spline. Функция поставляется с базой R, см. • smooth.spline для подробностей.
Чтобы получить ДЕЙСТВИТЕЛЬНО гладкую ...
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)
Этот стиль интерполирует множество дополнительных точек и дает вам очень гладкую кривую. Это также похоже на подход, который использует ggplot. Если стандартный уровень гладкости в порядке, вы можете просто использовать.
scatter.smooth(x, y)
LOESS - очень хороший подход, как сказал Дирк.
Другой вариант - использовать сплайны Безье, которые в некоторых случаях могут работать лучше, чем LOESS, если у вас мало точек данных.
Здесь вы найдете пример: http://rosettacode.org/wiki/Cubic_bezier_curves#R
# x, y: the x and y coordinates of the hull points
# n: the number of points in the curve.
bezierCurve <- function(x, y, n=10)
{
outx <- NULL
outy <- NULL
i <- 1
for (t in seq(0, 1, length.out=n))
{
b <- bez(x, y, t)
outx[i] <- b$x
outy[i] <- b$y
i <- i+1
}
return (list(x=outx, y=outy))
}
bez <- function(x, y, t)
{
outx <- 0
outy <- 0
n <- length(x)-1
for (i in 0:n)
{
outx <- outx + choose(n, i)*((1-t)^(n-i))*t^i*x[i+1]
outy <- outy + choose(n, i)*((1-t)^(n-i))*t^i*y[i+1]
}
return (list(x=outx, y=outy))
}
# Example usage
x <- c(4,6,4,5,6,7)
y <- 1:6
plot(x, y, "o", pch=20)
points(bezierCurve(x,y,20), type="l", col="red")