Nothing
## this is part of the implementation of the Penalized B-splines smoothers
## the new function uses singular value decomosition
## 22 -5 -15
## TO DO
## i) I put SVD for stability (for variable OK) we need it for factors now (OK finish)
## ii) should I use linear iteraction of x:z as I used to do or put it equal to zero?
## at the momment interaction is out because the terms plots are better without interactions
## this effects the df 's check again
## THERE IS A PROBLEM WITH DF's what Should I used (i think now is OK)
## iii) what should I save to produce sensible plots?
## for the variable by I think this parcialy is done by
## plotting b(x) against the x for factor we can plot the fitted lines in one or more plots
## iv) also when save var do I have to put the linear at the moment linear is out from the
## calulations of var? I think this is fixed
## I need to do the factors: check fixed lambda
## fixed df's
## estimating lamnda
## ML
## GAIC
## GVC
#-------------------------------------------------------------------------------
## Mikis Stasinopoulos and Bob Rigby with contribution from Paul Eilers
## last modified Saturday, June 8, 2015
## the pvc() function is a varying coefficients model function
#------------------------------------------------------------------------------
pvc<-function(x, df = NULL, lambda = NULL, by = NULL , control=pvc.control(...), ...)
{
## this function is based on Paul Eilers' penalised beta regression splines function
## lambda : is the smoothing parameter
## df : are the effective df's
## if both lambda=NULL and df=NULL then lambda is estimated using the different method
## methods are "ML", "GAIC" and "GCV"
## if df is set to number but lambda is NULL then df are used for smoothing
## if lambda is set to a number (whether df=NULL or not) lambda is used for smoothing
## the knots are defined in equal space unless quantiles=TRUE is set in the control function
# ---------------------------------------------------
## local function
## creates the basis for p-splines
## Paul Eilers' function
#-------------------------------------------------------------------------------
bbase <- function(x, xl, xr, ndx, deg, quantiles=FALSE)
{
tpower <- function(x, t, p)
# Truncated p-th power function
(x - t) ^ p * (x > t)
# DS xl= min, xr=max, ndx= number of points within
# Construct B-spline basis
# if quantiles=TRUE use different bases
dx <- (xr - xl) / ndx # DS increment
if (quantiles) # if true use splineDesign
{
knots <- sort(c(seq(xl-deg*dx, xl, dx),quantile(x, prob=seq(0, 1, length=ndx)), seq(xr, xr+deg*dx, dx)))
B <- splineDesign(knots, x = x, outer.ok = TRUE, ord=deg+1)
return(B)
}
else # if false use Paul's
{
knots <- seq(xl - deg * dx, xr + deg * dx, by = dx)
P <- outer(x, knots, tpower, deg)# calculate the power in the knots
n <- dim(P)[2]
D <- diff(diag(n), diff = deg + 1) / (gamma(deg + 1) * dx ^ deg) #
B <- (-1) ^ (deg + 1) * P %*% t(D)
B
}
}
#-------------------------------------------------------------------------------
#-------------------------------------------------------------------------------
# the main function starts here
scall <- deparse(sys.call())
no.dist.val <- length(table(x))
lx <- length(x)
control$inter <- if (lx<99) 10 else control$inter # this is to prevent singularities when length(x) is small:change to 99 30-11-11 MS
control$inter <- if (no.dist.val<=control$inter) no.dist.val else control$inter
xl <- min(x)
xr <- max(x)
xmax <- xr + 0.01 * (xr - xl)
xmin <- xl - 0.01 * (xr - xl)
X <- bbase(x, xmin, xmax, control$inter, control$degree, control$quantiles) # create the basis
r <- ncol(X)
## the penalty matrix
D <- if(control$order==0) diag(r) else diff(diag(r), diff=control$order) # the penalty matrix
## here we get the gamlss environment and a random name to save
## the starting values for lambda within gamlss()
## get gamlss environment
#--------
rexpr <- regexpr("gamlss",sys.calls())
for (i in length(rexpr):1)
{
position <- i
if (rexpr[i]==1) break
}
gamlss.environment <- sys.frame(position)
#--------
## get a random name to use it in the gamlss() environment
#--------
sl <- sample(letters, 4)
fourLetters <- paste(paste(paste(sl[1], sl[2], sep=""), sl[3], sep=""),sl[4], sep="")
startLambdaName <- paste("start.Lambda",fourLetters, sep=".")
## put the starting values in the gamlss()environment
#--------
assign(startLambdaName, control$start, envir=gamlss.environment)
#----------------------------------------------------------
if(is.null(by)) # if by is null behave as pb()
{
by.var <- NULL
xvar <- x
if(!is.null(df)) # degrees of freedom
{
if (df[1]>(dim(X)[2]-2))
{df <- 3;
warning("The df's exceed the number of columns of the design matrix", "\n", " they are set to 3") }
df <- if (any(df < 1)) 1 else df
if (any(df < 1) ) warning("the df are set to 1")
}
}
else # is by has a variable then here
{
if (is(by, "factor")) # if it a factor
{
by.var <- by
starting <- rep(control$start, nlevels(by))
assign(startLambdaName, starting, envir=gamlss.environment)
if(!is.null(df[1])) # degrees of freedom
{
if (length(df)!=nlevels(by)) df <- rep(df[1], nlevels(by))
if (any(df>(dim(X)[2]-2)))
{df <- ifelse((df>(dim(X)[2]-2)),3,df)
warning("The df's exceed the number of columns of the design matrix", "\n", " they are set to 3") }
df <- ifelse( df < 1, 1 , df)
if (any(df < 1)) warning("the df are set to 1")
}
}
else # if is not a factor
{ by.var <- by-mean(by) # take the mean of by out
if(!is.null(df)) # degrees of freedom
{
if (df>(dim(X)[2]-2))
{df <- 3;
warning("The df's exceed the number of columns of the design matrix", "\n", " they are set to 3") }
df <- if (df[1] < 1) 1 else df+2
if (df[1] < 1) warning("the df are set to 1")
}
}
xvar <- rep(0,length(x))#model.matrix(~by.var*x, contrast="") # put the linear interaction
}
attr(xvar, "control") <- control
attr(xvar, "D") <- D
attr(xvar, "X") <- X
attr(xvar, "df") <- df
attr(xvar, "by") <- by.var
attr(xvar, "xorig") <- x
attr(xvar, "call") <- substitute(gamlss.pvc(data[[scall]], z, w))
attr(xvar, "lambda") <- lambda
attr(xvar, "gamlss.env") <- gamlss.environment
attr(xvar, "NameForLambda") <- startLambdaName
attr(xvar, "class") <- "smooth"
xvar
}
#-------------------------------------------------------------------------------
#-------------------------------------------------------------------------------
# control function for pvc()
##------------------------------------------------------------------------------
pvc.control <- function(inter = 20, degree= 3, order = 2, start=10, quantiles=FALSE,
method=c("ML","GAIC", "GCV"), k=2, ...)
{
## Control function for pb()
## MS Tuesday, March 24, 2009
## inter : is the number of equal space intervals in x
## (unless quantiles = TRUE is used in which case the points will be at the quantiles values of x)
## degree: is the degree of the polynomial
## order refers to differences in the penalty for the coeficients
## order = 0 : white noise random effects
## order = 1 : random walk
## order = 2 : random walk of order 2
## order = 3 : random walk of order 3
# inter = 20, degree= 3, order = 2, start=10, quantiles=FALSE, method="loML"
if(inter <= 0) {
warning("the value of inter supplied is less than 0, the value of 10 was used instead")
inter <- 10 }
if(degree <= 0) {
warning("the value of degree supplied is less than zero or negative the default value of 3 was used instead")
degree <- 3}
if(order < 0) {
warning("the value of order supplied is zero or negative the default value of 2 was used instead")
order <- 2}
if(k <= 0) {
warning("the value of GAIC/GCV penalty supplied is less than zero the default value of 2 was used instead")
k <- 2}
method <- match.arg(method)
list(inter = inter, degree = degree, order = order, start=start,
quantiles = as.logical(quantiles)[1], method= method, k=k)
}
#-------------------------------------------------------------------------------
#-------------------------------------------------------------------------------
#-------------------------------------------------------------------------------
#-------------------------------------------------------------------------------
gamlss.pvc <- function(x, y, w, xeval = NULL, ...)
{
#-------------------------------------------------------------------------------
#-------------------------------------------------------------------------------
## functions within
## local function for simple penalized regression
regpen <- function(y, X, w, lambda, D)# original
{
RD <- rbind(R,sqrt(lambda)*D) # 2p x p matrix
svdRD <- svd(RD) # U 2pxp D pxp V pxp
rank <- sum(svdRD$d>max(svdRD$d)*.Machine$double.eps^.8)
U1 <- svdRD$u[1:p,1:rank] # U1 p x rank
y1 <- t(U1)%*%Qy # t(Q)%*%(sqrt(w)*y) # rankxp pxn nx1 => rank x 1 vector
beta <- svdRD$v[,1:rank] %*%(y1/svdRD$d[1:rank])
HH <- (svdRD$u)[1:p,1:rank]%*%t(svdRD$u[1:p,1:rank])
df <- sum(diag(HH))
fit <- list(beta = beta, edf = df)
return(fit)
}
#-------------------------------------------------------------------------------
#-------------------------------------------------------------------------------
## local function for penalised regression covariance model ~x*factor
## using expanding data
regpenByFactor <- function(y, X, w, fac, lambda, D)
{
sqrtLambda <-sqrt(lambda[as.numeric(rownames(BD))])
RD <- rbind(BR,sqrtLambda*BD) # 2p x p matrix
svdRD <- svd(RD) # U 2pxp D pxp V pxp
rank <- sum(svdRD$d>max(svdRD$d)*.Machine$double.eps^.8)
U1 <- svdRD$u[1:(p*nlev),1:rank] # U1 p x rank
y1 <- t(U1)%*%BQy # t(Q)%*%(sqrt(w)*y) # rankxp pxn nx1 => rank x 1 vector
beta <- svdRD$v[,1:rank] %*%(y1/svdRD$d[1:rank])
HH <- (svdRD$u)[1:dim(RD)[2],1:rank]%*%t(svdRD$u[1:dim(RD)[2],1:rank])
df <- sum(diag(HH))
fv <- BX %*%beta
fit <- list(beta = beta, edf = df, fv=fv)
return(fit)
}
#-------------------------------------------------------------------------------
#-------------------------------------------------------------------------------
## local function for penalised regression covariance model ~x+factor
## using matrix operators
# regpenByFactor1 <- function(y, X, w, fac, lambda, D) #
# {
# BX <- FbyX(fac, X) # get the interaction design matrix
# BD <- ExpandD(fac, D, lambda) # get the expanded penalty matrix
# G <- t(BD) %*% BD
# XW <- w * BX
# XWX <- t(XW) %*% BX
# beta <- solve(XWX + G, t(XW) %*% y)
# fv <- BX %*%beta
# H <- solve(XWX + G, XWX)
# fit <- list(fv=fv, beta = beta, edf = sum(diag(H)))
# return(fit)
# }
#-------------------------------------------------------------------------------
#-------------------------------------------------------------------------------
## local function to find lambda minimizing the local GAIC
fnGAIC <- function(lambda, k)
{
fit <- regpen(y=y, X=X, w=w, lambda=lambda, D)
fv <- X %*% fit$beta
GAIC <- sum(w*(y-fv)^2)+k*fit$edf
# cat("GAIC", GAIC,lambda, k,fit$edf, "\n")
GAIC
}
#-------------------------------------------------------------------------------
#-------------------------------------------------------------------------------
## local function to find lambdas miimizing the local GAIC
## here is for model ~X+factor
fnGAICforFactor <- function(lambda, k)
{
fit <- regpenByFactor(y=yvar, X=BX, w=w, fac=by.var, lambda=lambda, D=BD)
fv <- fit$fv
GAIC <- sum(w*(yvar-fv)^2)+k*fit$edf
# cat("GAIC", GAIC, "\n")
GAIC
}
#-------------------------------------------------------------------------------
#-------------------------------------------------------------------------------
## local function to find lambda minimising the local GCV
fnGCV <- function(lambda, k)
{
I.lambda.D <- (1+lambda*UDU$values)
edf <- sum(1/I.lambda.D)
y_Hy2 <- y.y-2*sum((yy^2)/I.lambda.D)+sum((yy^2)/((I.lambda.D)^2))
GCV <- (n*y_Hy2)/(n-k*edf)^2
GCV
}
#-------------------------------------------------------------------------------
#-------------------------------------------------------------------------------
## local function to find lambdas minimising the local GCV
## this is the case where the model is ~x+factor
fnGCVforFactor <- function(lambda, k)
{
fac <- as.factor(colnames(S))
lambdas <- model.matrix(~fac-1)%*%lambda
I.lambda.D <- (1+lambdas*UDU$values)
edf <- sum(1/I.lambda.D)
y_Hy2 <- y.y-2*sum((yy^2)/I.lambda.D)+sum((yy^2)/((I.lambda.D)^2))
GCV <- (n*y_Hy2)/(n-k*edf)^2
GCV
}
#-------------------------------------------------------------------------------
#-------------------------------------------------------------------------------
## local function to get df using eigen values
edf1_df <- function(lambda)
{
edf <- sum(1/(1+lambda*UDU$values))
(edf-df)
}
#-------------------------------------------------------------------------------
#-------------------------------------------------------------------------------
## local function to create the interaction desing matrix of the kind |X1 0|
FbyX<- function(fac, X) # |0 X2|
{ # this function is to create a factor * matrix interaction design matrix
A <- model.matrix(~fac-1, contrast="") #get the dummy matrix of the factor
nlev <- nlevels(fac)
for (i in 1:nlev)
{
NX <- A[,i]* X # interaction with each column
XX <- if (i==1) NX else cbind(XX,NX) # put it together
}
XX
}
#-------------------------------------------------------------------------------
#-------------------------------------------------------------------------------
## this function creates a general penalty function
## set lambda=1 if you just want the D's
# ExpandD <- function(fac,D, lambda) # i.e. | sqrt(lambda1)D_1 0 |
# { #creating a large penalty matrix | 0 sqrt(lambda2)D_2 |
# pos1 <- 1
# pos2 <- p2
# pos3 <- 1
# pos4 <- p
# BD <- matrix(0, nrow=nlev*p2, ncol=(nlev*p))
# cname <- rep(0, nlev*p)
# for (j in 1:nlev)
# {
# prow <- (pos1:pos2)
# pcol <- (pos3:pos4)
# pos1 <- pos2+1
# pos2 <- pos1+p2-1
# pos3 <- pos4+1
# pos4 <- pos3+p-1
# DD <- sqrt(lambda[j])*D
# BD[prow, pcol] <- DD
# cname[pcol] <- j
# }
# colnames(BD) <- cname
# BD
# }
#-------------------------------------------------------------------------------
#-------------------------------------------------------------------------------
ExpandD <- function(fac,D) # i.e. | sqrt(lambda1)D_1 0 |
{ #creating a large penalty matrix | 0 sqrt(lambda2)D_2 |
nlev <- nlevels(fac)
pos1 <- 1
pos2 <- p2 <- nrow(D)
pos3 <- 1
pos4 <- p <- ncol(D)
BD <- matrix(0, nrow=nlev*p2, ncol=(nlev*p))
cname <- rep(0, nlev*p)
rname <- rep(0, nlev*p2)
for (j in 1:nlev)
{
prow <- (pos1:pos2)
pcol <- (pos3:pos4)
pos1 <- pos2+1
pos2 <- pos1+p2-1
pos3 <- pos4+1
pos4 <- pos3+p-1
DD <- D
BD[prow, pcol] <- DD
cname[pcol] <- j
rname[prow] <- j
}
colnames(BD) <- cname
rownames(BD) <- rname
BD
}
#-------------------------------------------------------------------------------
#-------------------------------------------------------------------------------
#-------------------------------------------------------------------------------
# the main function starts here
# get the attributes
is.Factor <- FALSE # whether by is factor or variate
X <- if (is.null(xeval)) as.matrix(attr(x,"X")) #the trick is for prediction
else as.matrix(attr(x,"X"))[seq(1,length(y)),]
D <- as.matrix(attr(x,"D")) # penalty
lambda <- as.vector(attr(x,"lambda")) # lambda
df <- as.vector(attr(x,"df")) # degrees of freedom
by.var <- if (is.null(xeval)) attr(x,"by")
else attr(x,"by")[seq(1,length(y))]
x.orig <- if (is.null(xeval)) attr(x,"xorig")
else attr(x,"xorig")[seq(1,length(y))]
if (!is.null(by.var))
{
if (is.factor(by.var))
{
by.var <- as.factor(by.var)
is.Factor <- TRUE
}
else
{
by.var <- as.vector(by.var)
}
}
control <- as.list(attr(x, "control"))
gamlss.env <- as.environment(attr(x, "gamlss.env"))
startLambdaName <- as.character(attr(x, "NameForLambda"))
order <- control$order # the order of the penalty matrix
N <- sum(w!=0) # DS+FDB 3-2-14
n <- nrow(X) # the no of observations
p <- ncol(D) # the rows of the penalty matrix
p2 <- nrow(D)
tau2 <- sig2 <- NULL
w <- if (is.null(by.var)) w
else
{
if (is.factor(by.var)) w
else w*(by.var^2)
}
yvar <- if (is.null(by.var)) y
else
{
if (is.factor(by.var)) y
else (y/ifelse(by.var==0,0.0001,by.var))
}
## we need to know whether by.var is a factor or not
## if is not a factor fit :by= is a VARIABLE-----------------------------------
if (!is.Factor) # not a factor
{ # QR demposition
qrX <- qr(sqrt(w)*X, tol=.Machine$double.eps^.8)
R <- qr.R(qrX)
Q <- qr.Q(qrX)
Qy <- t(Q)%*%(sqrt(w)*yvar)
lambdaS <- get(startLambdaName, envir=gamlss.env) ## geting the starting value
if (lambdaS>=1e+07) lambda <- 1e+07 # MS 19-4-12
if (lambdaS<=1e-07) lambda <- 1e-07 # MS 19-4-12
## now the action depends on the values of lambda and df
##------------------------------------------------------------------------------
## case 1: if lambda is known just fit------------------------------------------
if (is.null(df)&&!is.null(lambda)||!is.null(df)&&!is.null(lambda))
{
fit <- regpen(yvar, X, w, lambda, D)
fv <- X %*% fit$beta #--------------------------end case 1------
} # case 2: if lambda is estimated ------------------------------------------
else if (is.null(df)&&is.null(lambda)) # estimate lambda
{ #
# cat("----------------------------","\n")
lambda <- get(startLambdaName, envir=gamlss.env) ## geting the starting value
# if ML ----------------------
switch(control$method, # which method to use for estimating lambda
"ML"={
for (it in 1:50)
{
fit <- regpen(yvar, X, w, lambda, D) # fit model
gamma. <- D %*% as.vector(fit$beta) # get the gamma differences
fv <- X %*% fit$beta # fitted values
sig2 <- sum(w * (yvar - fv) ^ 2) / (N - fit$edf)
tau2 <- sum(gamma. ^ 2) / (fit$edf-order)# Monday, March 16, 2009 at 20:00 see LNP page 279
lambda.old <- lambda
lambda <- sig2 / tau2 # maybe only 1/tau2 will do since it gives exactly the EM results see LM-1
if (lambda<1.0e-7) lambda<-1.0e-7 # DS Saturday, April 11, 2009 at 14:18
# cat("iter tau2 sig2",it,tau2, sig2, '\n')
if (abs(lambda-lambda.old) < 1.0e-7||lambda>1.0e7) break
assign(startLambdaName, lambda, envir=gamlss.env)
#cat("lambda",lambda, '\n')
}
},
"GAIC"=
{
lambda <- nlminb(lambda, fnGAIC, lower = 1.0e-7, upper = 1.0e7, k=control$k)$par
fit <- regpen(y=yvar, X=X, w=w, lambda=lambda, D)
fv <- X %*% fit$beta
assign(startLambdaName, lambda, envir=gamlss.env)
},
"GCV"={
#
# QR <-qr(sqrt(w)*X)
wy <- sqrt(w)*yvar
y.y <- sum(wy^2)
Rinv <- solve(R)
S <- t(D)%*%D
UDU <- eigen(t(Rinv)%*%S%*%Rinv)
yy <- t(UDU$vectors)%*%Qy #t(qr.Q(QR))%*%wy
lambda <- nlminb(lambda, fnGCV, lower = 1.0e-7, upper = 1.0e7, k=control$k)$par
fit <- regpen(y=yvar, X=X, w=w, lambda=lambda, D)
fv <- X %*% fit$beta
assign(startLambdaName, lambda, envir=gamlss.env)
})
} #--------------------------------------------------------end case 2 -------
else # case 3 : if df are required-------------------------------------------
{
#method 2 from Simon Wood (2006) pages 210-211, and 360
Rinv <- solve(R)
S <- t(D)%*%D
UDU <- eigen(t(Rinv)%*%S%*%Rinv)
lambda <- if (sign(edf1_df(0))==sign(edf1_df(100000))) 100000 # in case they have the some sign
else uniroot(edf1_df, c(0,100000))$root
# if (any(class(lambda)%in%"try-error")) {lambda<-100000}
fit <- regpen(y, X, w, lambda, D)
fv <- X %*% fit$beta
}#--------------------------------------------------------------end of case 3
waug <- as.vector(c(w, rep(1,nrow(D))))
xaug <- as.matrix(rbind(X,sqrt(lambda)*D))
lev <- hat(sqrt(waug)*xaug,intercept=FALSE)[1:n] # get the hat matrix
# lev <- (lev-.hat.WX(w,cbind(1,x.orig, by.var))) # subtract the linear since is already fitted
var <- lev/w # the variance of the smootherz
if (is.null(xeval)) # if no prediction
{
if(is.null(by.var))
{
list(fitted.values=fv, residuals=y-fv, var=var, nl.df = fit$edf-2,
lambda=lambda, coefSmo=list(coef=fit$beta, lambda=lambda, edf=fit$edf, tau2=tau2, sig2=sig2, method=control$method) )
}
else
{
# plot(fitted(lm(x.orig~X))~x.orig) x in the space of X
# plot(fitted(lm(by.var~X))~by.var) by not
coefSmo <- list(coef = fit$beta,
lambda = lambda,
edf = fit$edf,
sigb2 = tau2,
sige2 = sig2,
sigb = if (is.null(tau2)) NA else sqrt(tau2),
sige = if (is.null(sig2)) NA else sqrt(sig2),
x = x.orig,
by = by.var,
beta.x = fv,
fv = fv*by.var,
var = var,
is.Factor = is.Factor,
method = control$method)
class(coefSmo) <- "pvc"
out <- list(fitted.values = fv*by.var,
residuals = y-(fv*by.var),
var = var,
nl.df = fit$edf-1,
lambda = lambda,
coefSmo = coefSmo
)
}
}
else # for prediction
{
if(is.null(by.var)) # if by is null do what you do in pb()
{
ll <- dim(as.matrix(attr(x,"X")))[1]
nx <- as.matrix(attr(x,"X"))[seq(length(y)+1,ll),]
pred <- drop(nx %*% fit$beta)
}
else # if by is not null you
{
ll <- dim(as.matrix(attr(x,"X")))[1]
nx <- as.matrix(attr(x,"X"))[seq(length(y)+1,ll),]
by.varExtra <- attr(x,"by")[seq(length(y)+1,ll)]
pred <- drop(nx %*% fit$beta)*by.varExtra
}
pred
}
}# if by is NOT a FACTOR ends here --------------------------------------------
else # here is if.Factor==TRUE -----------------------------FACTOR---FACTOR
{# by is a FACTOR
nlev <- nlevels(by.var)
lev <- levels(by.var)
fit <- list(nlev)
coefbeta <- list(nlev)
fv <- rep(0, length(y))
vedf <- rep(0, nlev)
if (length(lambda)>nlev) stop("the length of lambda is more than the nlevels of by")
lambda <- if (length(lambda)!=nlev) rep(lambda, nlev)
else lambda
Index <- 1:length(yvar)
BX <- FbyX(by.var, X) # get the interaction design matrix
BD <- ExpandD(by.var, D) # get the expanded penalty matrix
# QR demposition of the expanded version
qrBX <- qr(sqrt(w)*BX, tol=.Machine$double.eps^.8)
BR <- qr.R(qrBX)
BQ <- qr.Q(qrBX)
BQy <- t(BQ)%*%(sqrt(w)*yvar)
if (is.null(df[1])&&!is.null(lambda[1])||!is.null(df[1])&&!is.null(lambda[1]))
{ # this is for fix lambdas
# case 1 for fixed lambdas -----------------------------------------------
fit <- regpenByFactor(yvar, BX, w, by.var, lambda, BD)
fv <- BX%*%fit$beta
edf <- fit$edf #-------------------- end case 1-------------------
} # case 2: if lambda is estimated ----------------------------------------
else if (is.null(df[1])&&is.null(lambda[1]))
{ #
#cat("----------------------------","\n")
lambda <- get(startLambdaName, envir=gamlss.env) ## getting the starting value
# if ML ----------------------
switch(control$method,
"ML"={## the method used here is to loop and fit the individual models
for (i in 1:nlev)
{
II <- by.var==lev[i]
N <- sum(II*w!=0)
In <- Index[II]
#cat("parameter",i,"\n")
qrX <- qr(sqrt(w[II])*X[II,], tol=.Machine$double.eps^.8)
R <- qr.R(qrX)
Q <- qr.Q(qrX)
Qy <- t(Q)%*%(sqrt(w[II])*yvar[II])
for (it in 1:50)
{
fit[[i]] <- regpen(yvar[II], X[II,], w[II], lambda[i], D)
vedf[i] <- fit[[i]]$edf
coefbeta[[i]] <- fit[[i]]$beta
lfv <- X[II,]%*%fit[[i]]$beta # fitted values
fv[In] <- lfv
gamma. <- D %*% as.vector(fit[[i]]$beta) # get the gamma differences
sig2 <- sum(w[II] * (y[II] - lfv) ^ 2) / (N - fit[[i]]$edf)
tau2 <- sum(gamma. ^ 2) / (fit[[i]]$edf-order)# Monday, March 16, 2009 at 20:00 see LNP page 279
lambda.old <- lambda[i]
lambda[i] <- sig2 / tau2 #
# cat("it lambda", it, lambda, "\n")
if (lambda[i]<1.0e-7) lambda[i]<-1.0e-7 # DS Saturday, April 11, 2009 at 14:18
if (lambda[i]>1.0e+7) lambda[i]<-1.0e+7 # DS Wednesday, July 29, 2009 at 19:00
if (abs(lambda[i]-lambda.old) < 1.0e-7||lambda[i]>1.0e7) break
}
}
assign(startLambdaName, lambda, envir=gamlss.env)
edf <- sum(vedf)
},
"GAIC"=
{ # note that here the expanded model is used so the search for lambda is in mupliple dimension
lambda <- nlminb(lambda, fnGAICforFactor, lower = rep(1.0e-7, nlev), upper = rep(1.0e7, nlev), k=control$k)$par # k=control$k)$par
fit <- regpenByFactor(yvar, BX, w, by.var, lambda, BD)
fv <- fit$fv
edf <- fit$edf
coefbeta <- fit$beta
assign(startLambdaName, lambda, envir=gamlss.env)
},
"GCV"={
## note that here the expanded model is used so the search for lambda is in mupliple dimension
BX <- FbyX(by.var, X) # get the interaction design matrix
BD <- ExpandD(by.var, D) # get the expanded penalty matrix
QR <-qr(sqrt(w)*BX)
wy <- sqrt(w)*y
y.y <- sum(wy^2)
Rinv <- solve(qr.R(QR))
S <- t(BD)%*%BD
UDU <- eigen(t(Rinv)%*%S%*%Rinv)
yy <- t(UDU$vectors)%*%t(qr.Q(QR))%*%wy
lambda <- nlminb(lambda, fnGCVforFactor, lower=rep(1.0e-7,nlev), upper=rep(1.0e7,nlev), k=control$k)$par
fit <- regpenByFactor(yvar, BX, w, by.var, lambda, BD)
fv <- fit$fv
edf <- fit$edf
coefbeta <- fit$beta
assign(startLambdaName, lambda, envir=gamlss.env)
})
}
else # case 3 : if df are required---------------------------------
{
#--------------------------------------------------
## local function to get df using eigen values
lambda <- if (is.null(lambda)) rep(0, nlev)
for (i in 1:nlev)
{
edf1_df1 <- function(lambda)
{
edf <- sum(1/(1+lambda*UDU$values))
(edf-df[i])
}
#----------------
II <- by.var==lev[i]
In <- Index[II]
QR <- qr(sqrt(w[II])*X[II,])
Rinv <- solve(qr.R(QR))
S <- t(D)%*%D
UDU <- eigen(t(Rinv)%*%S%*%Rinv)
lambda[i] <- if (sign(edf1_df1(0))==sign(edf1_df1(100000))) 100000 # in case they have the same sign
else uniroot(edf1_df1, c(0,100000))$root
if (any(class(lambda[i])%in%"try-error")) {lambda[i]<-100000}
}
fit <- regpenByFactor(yvar, BX, w, by.var, lambda, BD)
fv <- fit$fv
edf <- fit$edf
coefbeta <- fit$beta
assign(startLambdaName, lambda, envir=gamlss.env)
}#--------------------------------------------------------------------------end of case 3
# I need to calculate the hat matrix here for the variance of the smoother
BX <- FbyX(by.var, X) # get the interaction design matrix
BD <- ExpandD(by.var, D) # get the expanded penalty matrix
# needs lambda here
sqrtLambda <-sqrt(lambda[as.numeric(rownames(BD))])
waug <- as.vector(c(w, rep(1,nlev*p2)))
yaug <- as.vector(c(y, rep(0,nlev*p2)))
xaug <- as.matrix(rbind(BX,sqrtLambda*BD))
#fit1 <- lm.wfit(xaug,yaug,w=waug,method="qr")
#fit2 <- regpenByFactor(yvar, X, w, by.var, lambda, D)
#fit3 <- regpenByFactor1(yvar, X, w, by.var, lambda, D)
# the error is here
lev <- hat(sqrt(waug)*xaug,intercept=FALSE)[1:n] # get the hat matrix
#(sum(lev), "\n")
lev <- (lev-.hat.WX(w,rep(1,n))) # This has to checked????
var <- lev/w
## something not right here
#if (any(is.na(fv)))
if (is.null(xeval)) # if no prediction
{
# mm<-model.matrix(~by.var-1, contrast="")
# plot(fitted(lm(mm[,1]~BX))~mm[,1])
# plot(fitted(lm(mm[,2]~BX))~mm[,2])
coefSmo <- list(coef = fit$beta,
lambda = lambda,
edf = edf,
sigb2 = tau2,
sige2 = sig2,
sigb = if (is.null(tau2)) NA else sqrt(tau2),
sige = if (is.null(sig2)) NA else sqrt(sig2),
x = x.orig,
by = by.var,
fv = fv,
var = var,
is.Factor = is.Factor,
method = control$method)
class(coefSmo) <- "pvc"
out <- list(fitted.values = fv,
residuals = y-fv,
var = var,
nl.df = edf-nlev+1, # IS THIS CORRECT??????????????
lambda = lambda,
coefSmo = coefSmo)
# list(fitted.values = fv,
# residuals = y-fv,
# var = var,
# nl.df = sum(edf)-1 #(2*nlev),
# lambda = lambda,
# coefSmo = list( coef = coefbeta,
# lambda = lambda, edf=sum(edf), EDF=edf, tau2=NULL, sig2=NULL, method=control$method) )
}
else
{# Mikis 27-6-11
ll <- dim(as.matrix(attr(x,"X")))[1] # length of original X
nx <- as.matrix(attr(x,"X"))[seq(length(y)+1,ll),] # the x-values matrix
fac <- attr(x,"by")[seq(length(y)+1,ll)] # get the new values of the factor
BX <- FbyX(fac, nx) # get the interaction design matrix
longbeta <- as.vector(sapply(fit, function(l) l$beta)) # get the beta as a long vector
pred <- drop(BX %*% longbeta) # get prediction
pred
}
}
}
#------------------------------------------------------------------------------
#------------------------------------------------------------------------------
coef.pvc <- function(object, ...)
{
as.vector(object$coef)
}
#-----------------------------------------------------------------------------
fitted.pvc<- function(object, ...)
{
as.vector(object$fv)
}
#-----------------------------------------------------------------------------
print.pvc <- function (x, digits = max(3, getOption("digits") - 3), ...)
{
cat("P-varying coef. fit using the gamlss function pvc() \n")
cat("Degrees of Freedom for the fit :", x$edf, "\n")
cat("Random effect parameter sigma_b:", format(signif(x$sigb)), "\n")
cat("Smoothing parameter lambda :", format(signif(x$lambda)), "\n")
}
#-----------------------------------------------------------------------------
plot.pvc <- function(x,
scheme = c( "shaded", "lines"),
col.term = "darkred",
lwd.term = 1.5,
lty.se = 2 ,
lwd.se = 1,
col.se = "orange" ,
col.shaded = "gray",
factor.plots = FALSE, ...)
{
#--------------------------------------------------------------------------------
scheme <- match.arg(scheme)
is.Factor <- x$is.Factor
if (!is.Factor)
{
beta <- x$beta.x
var <- x$var
upper <- beta+2*sqrt(var)
lower <- beta -2*sqrt(var)
ran <- range(upper, lower)*c(.95, 1.05)
plot(beta[order(x$x)]~x$x[order(x$x)], type="l", ylim=ran,
ylab="b(x)", xlab="x" , main="varying coef.", col = col.term,
lwd = lwd.term)
if (scheme=="lines")
{
lines(x$x[order(x$x)], upper[order(x$x)] , lty = lty.se, lwd = lwd.se, col = col.se)
lines(x$x[order(x$x)], lower[order(x$x)], lty = lty.se, lwd = lwd.se, col = col.se)
} else
{
x1 <- x$x[order(x$x)]
xx <- c(x1,rev(x1))
yy <- c(lower[order(x$x)] , upper[rev(order(x$x))])
polygon(xx, yy, col = col.shaded, border = col.shaded)
lines(x$x[order(x$x)], beta[order(x$x)], col = col.term, lwd = lwd.term)
}
}
if (is.Factor)
{
fv <- as.vector(x$fv)
var <- x$var
upper <- fv+2*sqrt(var)
lower <- fv -2*sqrt(var)
ran <- range(upper, lower)*c(.95, 1.05)
if (!factor.plots)
{
plot(fv[order(x$x)]~x$x[order(x$x)], type="n", ylim=ran,
ylab="f(x)", xlab="x" , main="var. coef.", col = col.term,
lwd = lwd.term)
}
nlevs <- nlevels(x$by)
for (i in levels(x$by))
{
if (factor.plots)
{
plot(fv[order(x$x)]~x$x[order(x$x)], type="n", ylim=ran,
ylab="f(x)", xlab="x" , main=i, col = col.term,
lwd = lwd.term) # ds 5-1-18
}
fvi <- fv[x$by==i]
xi <- x$x[x$by==i]
ox <- order(xi)
upperi <- upper[x$by==i]
loweri <- lower[x$by==i]
if (scheme=="lines")
{
lines(xi[ox], upperi[ox] , lty = lty.se, lwd = lwd.se, col = col.se)
lines(xi[ox], loweri[ox], lty = lty.se, lwd = lwd.se, col = col.se)
lines(xi[ox], fvi[ox], col = col.term, lwd = lwd.term)
} else
{
x1 <- xi[ox]
xx <- c(x1,rev(x1))
yy <- c(loweri[ox] , upperi[rev(ox)])
polygon(xx, yy, col = col.shaded, border = col.shaded)
lines(xi[ox], fvi[ox], col = col.term, lwd = lwd.term)
}
}
}
}
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.