Visualisation d'une base spline

18

Les manuels ont généralement de beaux exemples de la base des splines uniformes lorsqu'ils expliquent le sujet. Quelque chose comme une rangée de petits triangles pour une spline linéaire, ou une rangée de petits bosses pour une spline cubique.

Voici un exemple typique:

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

Je me demande s'il existe un moyen facile de générer un tracé de la base de spline en utilisant des fonctions R standard (comme bs ou ns). Je suppose qu'il y a un simple morceau d'arithmétique matricielle combiné avec un programme R trivial qui crachera de jolies parcelles d'une base spline d'une manière élégante. Je ne peux pas y penser!

Patrick Caldon
la source

Réponses:

22

Essayez ceci, par exemple pour les splines B:

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)

Donner ceci:

entrez la description de l'image ici

jbowman
la source
4
Il est un peu plus efficace d'utiliser la matplotfonction plutôt que de parcourir les colonnes.
Greg Snow
C'est donc (+1), je ne sais pas pourquoi je l'ai laissé tomber de ma boîte à outils mentale.
jbowman
9

Voici une autoplotméthode pour la classe "base" (dont héritent à la fois bs et 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)
}

Cela vous permet d'appeler simplement autoplotun objet ns ou bs. Prenons l'exemple de jbowman:

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

qui produit:

Autoplot de base

Edit: Cela sera inclus dans la prochaine version du package ggfortify: https://github.com/sinhrks/ggfortify/pull/129 . Après cela, je crois que tout ce dont vous avez besoin est:

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