Question

I would like to fit a surface to some values:

x = 1:10
y = 10:1
z = sample(1:10,10)

I would like to fun something like spline_function(z ~ x + y). The actual spline functions in R seem to take only x and y so that i cannot have a two dimensional x coordinate. What is the way to do this in R? I am aware of loess for local polynomials etc. but splines is really what I am looking for.

Was it helpful?

Solution

One good option is the mgcv package which comes with all versions of R. It has isotropic penalised regression splines of two or more variables via s() and anisotropic penalised regression splines of two or more variables via tensor products and te().

If you don't want penalised regression splines, you can use argument fx = TRUE to fix known degree of freedom splines.

Here is an example from ?te

# following shows how tensor pruduct deals nicely with 
# badly scaled covariates (range of x 5% of range of z )
require(mgcv)
test1 <- function(x, z ,sx=0.3, sz=0.4) { 
  x <- x*20
  (pi ** sx * sz) * (1.2 * exp(-(x - 0.2)^2 / sx^2 - ( z - 0.3)^2 / sz^2) +
  0.8 * exp(-(x - 0.7)^2 / sx^2 -(z - 0.8)^2 / sz^2))
}
n <- 500

old.par<-par(mfrow=c(2,2))
x <- runif(n) / 20
z<-runif(n)
xs <- seq(0, 1, length=30) / 20
zs <- seq(0, 1, length=30)
pr <- data.frame(x=rep(xs, 30), z=rep(zs, rep(30, 30)))
truth <- matrix(test1(pr$x, pr$z), 30, 30)
f <- test1(x, z)
y <- f + rnorm(n) * 0.2

## model 1 with s() smooths
b1 <- gam(y ~ s(x,z))
persp(xs, zs, truth)
title("truth")
vis.gam(b1)
title("t.p.r.s")

## model 2 with te() smooths
b2 <- gam(y ~ te(x, z))
vis.gam(b2)
title("tensor product")

## model 3 te() smooths specifying margin bases
b3 <- gam(y ~ te(x, z, bs=c("tp", "tp")))
vis.gam(b3)
title("tensor product")
par(old.par)

enter image description here

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top