require(mgcv)
nei.cor <- function(h,n) { ## construct nei structure
nei <- list(md=1:n,d=1:n)
nei$ma <- cumsum(c((h+1):(2*h+1),rep(2*h+1,n-2*h-2),(2*h+1):(h+1)))
a0 <- rep(0,0); if (h>0) for (i in 1:h) a0 <- c(a0,1:(h+i))
a1 <- n-a0[length(a0):1]+1
nei$a <- c(a0,1:(2*h+1)+rep(0:(n-2*h-1),each=2*h+1),a1)
nei
}
set.seed(1)
n <- 500;sig <- .6
x <- 0:(n-1)/(n-1)
f <- sin(4*pi*x)*exp(-x*2)*5/2
e <- rnorm(n,0,sig)
for (i in 2:n) e[i] <- 0.6*e[i-1] + e[i]
y <- f + e ## autocorrelated data
nei <- nei.cor(4,n) ## construct neighbourhoods to mitigate
b0 <- gam(y~s(x,k=40)) ## GCV based fit
gc <- gam.control(ncv.threads=2)
b1 <- gam(y~s(x,k=40),method="NCV",nei=nei,control=gc)
## use "QNCV", which is identical here...
b2 <- gam(y~s(x,k=40),method="QNCV",nei=nei,control=gc)
## plot GCV and NCV based fits...
f <- f - mean(f)
par(mfrow=c(1,2))
plot(b0,rug=FALSE,scheme=1);lines(x,f,col=2)
plot(b1,rug=FALSE,scheme=1);lines(x,f,col=2)
#####################################
## example using randomly thinned nei
#####################################
sample.nei <- function(ii,a,ma) {
## thin down neighbourhood structures, retaining folds in ii
m1 <- ma[ii] ## ... neighbourhood ends and starts...
m0 <- 1 + if (ii[1]==1) c(0,ma[ii[-1]-1]) else ma[ii-1]
lena <- m1-m0+1
a <- a[sequence(lena,m0)]
ma <- cumsum(lena)
list(a=a,ma=ma)
}
ii <- sort(sample(n,200))
ne1 <- nei
ne1[c("a","ma")] <- sample.nei(ii,nei$a,nei$ma)
ne1[c("d","md")] <- sample.nei(ii,nei$d,nei$md)
b3 <- gam(y~s(x,k=40),method="NCV",nei=ne1,control=gc)
plot(b0,rug=FALSE,scheme=1);lines(x,f,col=2)
## note CI's not corrected for correlation in this case
plot(b3,rug=FALSE,scheme=1);lines(x,f,col=2)
z <- rpois(n,exp(y+1)) ## other families
b4 <- gam(z~s(x,k=40),family=poisson,control=gc)
b5 <- gam(z~s(x,k=40),method="NCV",family=tw,nei=ne1,control=gc)
Run the code above in your browser using DataLab