Visualizando uma base de spline

18

Normalmente, os livros didáticos têm bons exemplos de parcelas da base para splines uniformes ao explicar o tópico. Algo como uma fileira de pequenos triângulos para uma spline linear ou uma fileira de pequenas corcovas para uma spline cúbica.

Este é um exemplo típico:

http://support.sas.com/documentation/cdl/en/statug/63033/HTML/default/viewer.htm#statug_introcom_a0000000525.htm

Gostaria de saber se existe uma maneira fácil de gerar um gráfico da base spline usando funções R padrão (como bs ou ns). Eu acho que há um pedaço simples de aritmética de matriz combinada com um programa trivial de R que cuspirá uma bela parcela de uma base de spline de maneira elegante. Eu simplesmente não consigo pensar nisso!

Patrick Caldon
fonte

Respostas:

22

Tente isso, como um exemplo para B-splines:

x <- seq(0, 1, by=0.001)
spl <- bs(x,df=6)
plot(spl[,1]~x, ylim=c(0,max(spl)), type='l', lwd=2, col=1, 
     xlab="Cubic B-spline basis", ylab="")
for (j in 2:ncol(spl)) lines(spl[,j]~x, lwd=2, col=j)

Dando isso:

insira a descrição da imagem aqui

jbowman
fonte
4
É um pouco mais eficiente usar a matplotfunção em vez de percorrer as colunas.
Greg Snow
Então é (+1), não sei por que o tirei do meu kit de ferramentas mentais.
jbowman
9

Aqui está um autoplotmétodo para a classe "base" (da qual herda bs e ns):

library(ggplot2)
library(magrittr)
library(reshape2)
library(stringr)
autoplot.basis <- function(basis, n=1000) {
    all.knots <- sort(c(attr(basis,"Boundary.knots") ,attr(basis, "knots"))) %>%
        unname
    bounds <- range(all.knots)
    knot.values <- predict(basis, all.knots) %>%
        set_colnames(str_c("S", seq_len(ncol(.))))
    newx <- seq(bounds[1], bounds[2], length.out = n+1)
    interp.values <- predict(basis, newx) %>%
        set_colnames(str_c("S", seq_len(ncol(.))))
    knot.df <- data.frame(x=all.knots, knot.values) %>%
        melt(id.vars="x", variable.name="Spline", value.name="y")
    interp.df <- data.frame(x=newx, interp.values) %>%
        melt(id.vars="x", variable.name="Spline", value.name="y")
    ggplot(interp.df) +
        aes(x=x, y=y, color=Spline, group=Spline) +
        geom_line() +
        geom_point(data=knot.df) +
        scale_color_discrete(guide=FALSE)
}

Isso permite apenas chamar autoplotum objeto ns ou bs. Tomando o exemplo de jbowman:

library(splines)
x <- seq(0, 1, by=0.001)
spl <- bs(x,df=6)
autoplot(spl)

que produz:

Plotagem automática de base

Editar: Isso será incluído na próxima versão do pacote ggfortify: https://github.com/sinhrks/ggfortify/pull/129 . Depois disso, acredito que tudo que você precisa é:

library(splines)
library(ggfortify)
x <- seq(0, 1, by=0.001)
spl <- bs(x,df=6)
autoplot(spl)
Ryan C. Thompson
fonte