Установите сплайн B на контрольном пути

Я понимаю, что существует множество вопросов и ответов об использовании B-сплайнов в R, но мне еще предстоит найти ответ на этот (на первый взгляд простой) вопрос.

Учитывая набор точек, которые описывают контрольный путь, как вы подгоняете к нему кривую B-сплайна и извлекаете определенное количество точек (скажем, 100) вдоль кривой для построения графика. Подвох в том, что путь не является монотонным ни по x, ни по y.

Пример управляющего пути:

path <- data.frame(
    x = c(3, 3.5, 4.6875, 9.625, 5.5625, 19.62109375, 33.6796875, 40.546875, 36.59375, 34.5, 33.5, 33),
    y = c(0, 1, 4, 5, 6, 8, 7, 6, 5, 2, 1, 0)
)

Я в основном смотрел на splines пакет, но опять же, большинство примеров касалось подгонки гладкой кривой к данным. Для контекста я смотрю на реализацию иерархического связывания ребер в R.

1 ответ

Решение

Общая идея состоит в том, чтобы предсказывать x и y независимо, предполагая, что они фактически независимы:

library(splines)

path <- data.frame(
    x = c(3, 3.5, 4.6875, 9.625, 5.5625, 19.62109375, 33.6796875, 40.546875, 36.59375, 34.5, 33.5, 33),
    y = c(0, 1, 4, 5, 6, 8, 7, 6, 5, 2, 1, 0)
)
# add the time variable
path$time  <- seq(nrow(path))

# fit the models
df  <-  5
lm_x <- lm(x~bs(time,df),path)
lm_y <- lm(y~bs(time,df),path)

# predict the positions and plot them
pred_df  <-  data.frame(x=0,y=0,time=seq(0,nrow(path),length.out=100) )
plot(predict(lm_x,newdata = pred_df),
     predict(lm_y,newdata = pred_df),
     type='l')

вам нужно быть осторожным при определении переменной времени, поскольку путь не зависит от выбора времени (даже если они последовательные), поскольку сплайны не являются инвариантными относительно расстояния между точками в пространстве предиктора. Например:

plotpath  <-  function(...){
    # add the time variable with random spacing
    path$time  <- sort(runif(nrow(path)))

    # fit the models
    df  <-  5
    lm_x <- lm(x~bs(time,df),path)
    lm_y <- lm(y~bs(time,df),path)

    # predict the positions and plot them
    pred_df  <-  data.frame(x=0,y=0,time=seq(min(path$time),max(path$time),length.out=100) )
    plot(predict(lm_x,newdata = pred_df),
         predict(lm_y,newdata = pred_df),
         type='l',...)
}

par(ask=TRUE); # wait until you click on the figure or hit enter to show the next figure
for(i in 1:5)
    plotpath(col='red')
Другие вопросы по тегам