# code based on files "Code regarding section 4.2", "Code regarding section 4.3-4.4", # "Code regarding section 4.5" and "Code regarding section 4.6" # (copyright 2003, 2004, 2012 A.Azzalini and B.Scarpa) # call the necessary libraries library(splines) library(gam) library(sm) # auxiliary function, just to make plots convex.hull <- function(x, eval.points) { ngrid <- nrow(eval.points) hull.points <- x[order(x[, 1], x[, 2]), ] dh <- diff(hull.points) hull.points <- hull.points[c(TRUE, !((dh[, 1] == 0) & (dh[, 2] == 0))), ] hull.points <- hull.points[chull(hull.points), ] nh <- nrow(hull.points) gstep <- matrix(rep(eval.points[2, ] - eval.points[1, ], nh), ncol = 2, byrow = TRUE) hp.start <- matrix(rep(eval.points[1, ], nh), ncol = 2, byrow = TRUE) hull.points <- hp.start + gstep * round((hull.points - hp.start)/gstep) hull.points <- hull.points[chull(hull.points), ] grid.points <- cbind(rep(eval.points[ , 1], ngrid), rep(eval.points[ , 2], rep(ngrid, ngrid))) D <- diff(rbind(hull.points, hull.points[1, ])) temp <- D[, 1] D[, 1] <- D[, 2] D[, 2] <- (-temp) C <- as.vector((hull.points * D) %*% rep(1, 2)) C <- matrix(rep(C, ngrid^2), nrow = ngrid^2, byrow = TRUE) D <- t(D) wy <- ((grid.points %*% D) >= C) wy <- apply(wy, 1, all) wy[wy] <- 1 wy[!wy] <- NA wy <- matrix(wy, ncol = ngrid) wy } # read the data auto <- read.table("http://azzalini.stat.unipd.it/Book-DM/auto.dat", header = TRUE) attach(auto) xlab <- "Engine size (L)" ylab <- "Curb weight (kg)" zlab <- "City distance (km/L)" # define the variable (y = response, x1 and x2 covariates) y <- city.distance x1 <- engine.size x2 <- curb.weight # fit an additive model (gam without specifying "family" fits an additive model) a2 <- gam(city.distance ~ s(engine.size) + s(curb.weight), data = auto) pa2 <- preplot(a2) # figure 4.12a plot(pa2$"s(engine.size)", se = TRUE, ylim = c(-7, 10), lwd = 2, xlab = "Engine size", ylab = "s(Engine size)") # figure 4.12b plot(pa2$"s(curb.weight)", se = TRUE, ask = TRUE, ylim = c(-7,10), lwd = 2, xlab = "Curb weight", ylab = "s(Curb weight)") # order the values for display reasons x1 <- seq(min(engine.size), max(engine.size), length = 50) x2 <- seq(min(curb.weight), max(curb.weight), length = 50) x12<- data.frame( engine.size = as.vector(outer(x1, rep(1, length(x1)))), curb.weight = as.vector(outer(rep(1, length(x2)), x2))) a2p <- predict(a2, x12) sm.options(ngrid = 50) h<- c(0.5, 150) # figure 4.13a matrice.gam <- matrix(a2p, 50, 50) w1<-convex.hull(cbind(engine.size, curb.weight), cbind(x1, x2)) persp(x1, x2, matrice.gam * w1, theta = 120, phi = 20, xlab = "Engine size", ylab = "Curb weight", zlab = "City distance", ticktype = "detailed") # figure 4.13b sm <- sm.regression(cbind(engine.size, curb.weight), city.distance, h = h, options=list(xlab = xlab, ylab = ylab, zlab = zlab), display = "none") matrice.sm <- matrix(sm$estimate, 50, 50) persp(x1, x2, matrice.sm, theta = 120, phi = 20, xlab = "Engine size", ylab = "Curb weight", zlab = "City distance", ticktype = "detailed")