Nothing
#' @title Multiscale Geographically Weighted Elliptical Regression
#' @import spgwr
#' @import graphics
#' @import methods
#' @import sp
#' @import spData
#' @import maptools
#' @importFrom GWmodel gw.dist gw.weight Generate.formula
#' @name gwer.multiscale
#' @description The function fit geographically weighted elliptical regression model to explore the non-stationarity relationshps across differente spatial scales.
#' @param formula regression model formula as in \code{glm}.
#' @param kernel function chosen as follows:
#' gaussian: wgt = exp(-.5*(vdist/bw)^2);
#' exponential: wgt = exp(-vdist/bw);
#' bisquare: wgt = (1-(vdist/bw)^2)^2 if vdist < bw, wgt=0 otherwise;
#' tricube: wgt = (1-(vdist/bw)^3)^3 if vdist < bw, wgt=0 otherwise;
#' boxcar: wgt=1 if dist < bw, wgt=0 otherwise
#' @param adaptive defines the type of bandwidth used. either NULL (default) or a proportion between 0 and 1 of observations to include in weighting scheme (k-nearest neighbours).
#' @param criterion criterion for determining the convergence of the back-fitting procedure, could be "CVR" or "dCVR", which corespond to the changing value of RSS (CVR) and the differential version (dCVR), respectively; and "dCVR" is used as default.
#' @param hatmatrix if TRUE, return the hatmatrix as a component of the result.
#' @param spdisp if TRUE dispersion parameter varies geographically.
#' @param family a description of the error distribution to be used in the model (see \code{\link{family.elliptical}} for details of family functions).
#' @param data model data frame, or may be a SpatialPointsDataFrame or SpatialPolygonsDataFrame as defined in package \pkg{sp}.
#' @param dispersion an optional fixed value for dispersion parameter.
#' @param weights an optional numeric vector of weights to be used in the fitting process.
#' @param subset an optional numeric vector specifying a subset of observations to be used in the fitting process.
#' @param na.action a function which indicates what should happen when the data contain NAs (see \code{glm}).
#' @param longlat TRUE if point coordinates are longitude-latitude decimal degrees, in which case distances are measured in kilometers. If x is a SpatialPoints object, the value is taken from the object itself.
#' @param control a list of parameters for controlling the fitting process. For \code{elliptical} this is passed by \code{glm.control}.
#' @param max.iterations maximum number of iterations in the back-fitting procedure.
#' @param threshold threshold value to terminate the back-fitting iteration.
#' @param dMats a list of distance matrices used for estimating each specific parameter
#' @param p.vals a collection of positive numbers used as the power of the Minkowski distance
#' @param theta.vals a collection of values used as angles in radians to rotate the coordinate system
#' @param bws0 a vector of initializing bandwidths for the back-fitting procedure, of which the length should equal to the number of paramters if specified
#' @param bw.seled a vector of boolean variables to determine whether the corresponding bandwidth should be re-selected or not: if TRUE, the corresponding bandwiths for the specific parameters are supposed to be given in bws0; otherwise, the bandwidths for the specific parameters will be selected within the back-fitting iterations.
#' @param approach specified by CV for cross-validation approach or by AIC corrected (AICc) approach
#' @param bws.thresholds threshold values to define whether the bandwidth for a specific parameter has converged or not
#' @param bws.reOpts the number times of continually optimizing each parameter-specific bandwidth even though it meets the criterion of convergence, for avoiding sub-optimal choice due to illusion of convergence;
#' @param verbose if TRUE (default) reports the progress of search for bandwidth.
#' @param predictor.centered a logical vector of length equalling to the number of predictors, and note intercept is not included; if the element is TRUE, the corresponding predictor will be centered.
#' @param nlower the minmum number of nearest neighbours if an adaptive kernel is used
#' @param model a logical value indicating whether model frame should be included as a component of the return.
#' @param x a logical value indicating whether the response vector used in the fitting process should be returned as components of the return.
#' @param y a logical value indicating whether model matrix used in the fitting process should be returned as components of the return.
#' @param contrasts an optional list. See the \code{contrasts.arg} of \code{model.matrix.default}.
#' @param parplot if TRUE the parameters boxplots are plotted.
#' @param offset this can be used to specify an a priori known component to be included in the linear predictor during fitting as in \code{glm}.
#' @param ... arguments to be used to form the default control argument if it is not supplied directly.
#' @return returns an object of class \dQuote{gwer}, a list with follow components:
#' \item{SDF}{a SpatialPointsDataFrame (may be gridded) or SpatialPolygonsDataFrame object (see package \pkg{sp}) with fit.points, weights, GWR coefficient estimates, dispersion and the residuals in its \code{data} slot.}
#' \item{coef}{the matrices of coefficients, standard errors and significance values for parameters hypothesis test.}
#' \item{dispersion}{either the supplied argument or the estimated dispersion with standard error.}
#' \item{hat}{hat matrix of the geographically weighted elliptical model.}
#' \item{lm}{elliptical global regression on the same model formula.}
#' \item{results}{a list of results values for fitted geographically weighted elliptical model.}
#' \item{bandwidth}{the bandwidth used in geographical weighting function.}
#' \item{fitted}{the fitted mean values of the geographically weighted elliptical model.}
#' \item{hatmatrix}{a logical value indicating if hatmatrix was considered}
#' \item{gweights}{a matrix with the geographical weighting for all local elliptical models.}
#' \item{family}{the \code{family} object used.}
#' \item{flm}{a matrix with the fitted values for all local elliptical models.}
#' \item{adapt}{the \code{adapt} object used.}
#' \item{gweight}{the \code{gweights} object used.}
#' \item{spdisp}{the \code{spdisp} object used.}
#' \item{this.call}{the function call used.}
#' \item{fp.given}{the \code{fp.given} object used.}
#' \item{longlat}{the \code{longlat} object used.}
#' @references Brunsdon, C., Fotheringham, A. S. and Charlton, M. E. (1996).
#' Geographically weighted regression: a method for exploring spatial nonstationarity.
#' Geographical analysis, 28(4), 281-298. \doi{10.1111/j.1538-4632.1996.tb00936.x}
#' @references Fang, K. T., Kotz, S. and NG, K. W. (1990, ISBN:9781315897943).
#' Symmetric Multivariate and Related Distributions. London: Chapman and Hall.
#' @seealso \code{\link{bw.gwer}}, \code{\link{elliptical}}, \code{\link{family.elliptical}}
#' @keywords Geographically weighted regression
#' @keywords Bandwidth optimization
#' @keywords Elliptical model
#' @examples
#' \donttest{
#' data(georgia, package = "spgwr")
#' fit.formula <- PctBach ~ TotPop90 + PctRural + PctFB + PctPov
#' gwer.bw.t <- bw.gwer(fit.formula, data = gSRDF, family = Student(3), adapt = TRUE)
#' msgwr.fit.t <- gwer.multiscale(fit.formula, family = Student(3), data = gSRDF,
#' bws0 = rep(gwer.bw.t, 5), hatmatrix = TRUE,
#' adaptive = TRUE)
#' }
#' @rdname gwer.multiscale
#' @export
gwer.multiscale <- function (formula, data, kernel = "bisquare", approach = "CV", adaptive = FALSE, criterion = "dCVR",
family = Normal, threshold = 0.00001, dMats, p.vals, theta.vals, longlat = NULL, bws0,
bw.seled = rep(F, length(bws0)), bws.thresholds = rep(0.1, length(dMats)), bws.reOpts = 5,
spdisp = 'local', verbose = F, weights, dispersion = NULL, na.action = "na.fail", hatmatrix = T,
control = glm.control(epsilon = 1e-04, maxit = 100, trace = F), model = FALSE, x = FALSE,
y = TRUE, contrasts = NULL, parplot = FALSE, max.iterations = 2000, subset, offset,
predictor.centered = rep(T, length(bws0) - 1), nlower = 10, ...)
{
timings <- list()
timings[["start"]] <- Sys.time()
call <- match.call()
this.call <- match.call()
dist <- as.character(call$family)[1]
user.def <- F
if (!charmatch(dist, c("Normal", "Cauchy", "Student", "Gstudent", "LogisI", "LogisII", "Glogis", "Cnormal", "Powerexp"), nomatch = F))
dist <- match.arg(dist, c("Normal", "Cauchy", "Student", "Gstudent", "LogisI", "LogisII", "Glogis", "Cnormal", "Powerexp"))
else user.def <- T
p4s <- as.character(NA)
if (is(data, "Spatial")) {
p4s <- proj4string(data)
dp.locat <- coords <- coordinates(data)
regression.points <- data
data <- as(data, "data.frame")
}
else {
stop("Given regression data must be Spatial*DataFrame")
}
if (is.null(longlat) || !is.logical(longlat))
longlat <- FALSE
if (is.null(colnames(coords)))
colnames(coords) <- c("coord.x", "coord.y")
if (is.character(family))
family <- get(family, mode = "function", envir = parent.frame())
if (is.function(family))
family <- family()
if (is.null(family$family)) {
print(family)
stop("'family' not recognized")
}
if (missing(data))
data <- environment(formula)
mf <- match.call(expand.dots = FALSE)
m <- match(c("formula", "data"), names(mf), 0L)
mf <- mf[c(1L, m)]
mf$family <- mf$control <- mf$model <- mf$dispersion <- mf$x <- mf$y <- mf$kernel <- mf$adaptive <- mf$longlat <-mf$contrasts <- mf$offset <- mf$hatmatrix <- mf$spdisp <- mf$parplot <- mf$... <- NULL
mf$drop.unused.levels <- TRUE
mf[[1L]] <- as.name("model.frame")
mf <- eval(mf, parent.frame())
mt <- attr(mf, "terms")
dp.n <- nrow(dp.locat)
if (!missing(family) && !charmatch(dist, c("Normal", "Cauchy", "Student", "Gstudent", "LogisI", "LogisII", "Glogis", "Cnormal", "Powerexp"), F))
cat(paste("\n work with user-defined family:", call$family, "\n"))
if (!missing(dispersion) && is.numeric(dispersion) && !(dispersion > 0))
stop("\n no negative values for dispersion parameter")
Y <- model.extract(mf, "response")
if (!is.numeric(Y))
stop("\n response must be numeric")
X <- model.matrix(mt, mf, contrasts)
if (!is.numeric(X))
stop("\n model matrix must be numeric")
offset <- model.extract(mf, offset)
nobs <- nrow(X)
var.n <- ncol(X)
if (length(offset) == 1 && offset == 0)
offset <- rep(0, nobs)
idx1 <- match("(Intercept)", colnames(X))
w <- model.extract(mf, weights)
wzero <- rep(F, nrow(mf))
if (!length(w))
w <- rep(1, nrow(mf))
else if (any(w < 0))
stop("\n negative weights not allowed")
else {
wzero <- (w == 0)
Y.org <- Y
X.org <- X
offset.org <- offset
Y <- Y * w
X <- diag(c(w)) %*% X
offset <- w * offset
if (any(wzero)) {
wpos <- !wzero
fitted <- resid <- q1 <- q2 <- Y.org
Y <- Y[wpos]
X <- as.matrix(X[wpos, ])
offset <- offset[wpos]
}
}
# method <- "gwer.ms.fit"
# elliptical.fitter <- get(method)
offset4fit <- offset
# fit <- elliptical.fitter(X = X, Y = Y, offset = offset4fit, family = family,
# dispersion = dispersion, maxit = control$maxit,
# epsilon = control$epsilon, trace = control$trace, ...)
fit <- elliptical(formula = formula, family = family, data = data, dispersion = dispersion,
control = control, offset = offset4fit)
if (spdisp == 'global')
dispersion <- fit$dispersion
dispersion <- rep(dispersion, dp.n)
fit$x <- X
fit$y <- Y
if (!is.na(idx1)) {
if (length(predictor.centered) != var.n - 1) {
predictor.centered <- rep(T, length.out = var.n - 1)
warning("All the predictors will be centered, please check the parameter predictor.centered")
}
}
else {
if (length(predictor.centered) != var.n) {
predictor.centered <- rep(T, length.out = var.n)
warning("All the predictors will be centered, please check the parameter predictor.centered")
}
}
n.cent <- length(which(predictor.centered))
if(!is.na(idx1)) {
colnames(X)[idx1] <- "Intercept"
X1 <- X[,-idx1]
}
else {
X1 <- X
}
if(n.cent > 1)
predictors.centered.means <- colMeans(X1[,predictor.centered])
else if (n.cent == 1)
predictors.centered.means <- mean(X1[,predictor.centered])
else
predictors.centered.means <- NA
if(n.cent >= 1) {
X1[,predictor.centered] <- scale(X1[,predictor.centered], scale=FALSE)
}
if(!is.na(idx1))
{
X1 <- cbind(1, X1)
}
colnames(X1) <- colnames(X)
allvars <- all.vars(formula)
DeVar <- allvars[1]
InDevars <- colnames(X)
if(missing(dMats)) {
dMats <- list()
if(missing(p.vals)) {
p.vals <- 2
dMat <- gw.dist(dp.locat, longlat = longlat)
for(i in 1:var.n)
dMats[[i]] <- dMat
}
else {
p.vals <- rep_len(p.vals, var.n)
if(missing(theta.vals))
theta.vals <- rep_len(0, var.n)
else
theta.vals <- rep_len(theta.vals, var.n)
for(i in 1:var.n){
dMats[[i]] <- gw.dist(dp.locat, p = p.vals[i], theta = theta.vals[i], longlat = longlat)
}
}
}
else if(is.list(dMats)) {
if(length(dMats) != var.n)
stop("Please specify a distance matrix for each independent variable!")
else {
for(i in 1:var.n){
dim.dMat <- dim(dMats[[i]])
if (dim.dMat[1] != dp.n || dim.dMat[2] != dp.n)
stop("Dimensions of dMat are not correct")
}
}
}
else {
stop("dMats are not correct")
}
if(missing(bws0)) {
bws0 <- numeric(var.n)
cat("------ Calculate the initial bandwidths for each independent variable ------\n")
for(i in 1:var.n) {
if(InDevars[i] == "Intercept")
fml <- Generate.formula(DeVar, c("1"))
else {
fml <- Generate.formula(DeVar, c(InDevars[i]))
}
cat("Now select an optimum bandwidth for the model: ", fml, "\n")
part1 <- paste("bws0[i]<-bw.gwr(", fml, sep="")
part2 <- "data=regression.points,kernel=kernel,approach=approach,dMat=dMats[[i]])"
expression <- paste(part1, part2, sep=",")
print(expression)
eval(parse(text = expression))
# bws0[i] <- bw.gwer(X1, Y, dp.locat, approach = approach, kernel = kernel, adaptive = adaptive,
# dMat, verbose = verbose, nlower = nlower)
}
cat("------ The end for the initial selections ------\n")
}
else {
bws0 <- rep(bws0, length.out = var.n)
}
if(length(bw.seled) != var.n)
bw.seled <- rep(F, length.out = var.n)
cat("------ Calculate the initial beta0 from the above bandwidths ------\n")
dMat <- dMats[[1]]
bw.int0 <- bw.gwer1(X1, Y, dp.locat = dp.locat, approach = approach, kernel = kernel, adaptive = adaptive,
dispersion = dispersion, dMat = dMat, family = family, verbose = verbose, nlower = nlower)
if(hatmatrix) {
Shat <- matrix(nrow = dp.n, ncol = dp.n)
S.arrays <- array(dim = c(var.n, dp.n, dp.n))
H <- matrix(nrow = dp.n, ncol = dp.n)
H.arrays <- array(dim = c(var.n, dp.n, dp.n))
C <- array(dim=c(dp.n, var.n, dp.n))
}
ms.gweights <- array(dim = c(var.n, dp.n, dp.n))
fit.gwer <- gwer.mfit(X1, Y, family = family, loc = dp.locat, adaptive = adaptive, hatmatrix = hatmatrix, bw = bw.int0, kernel = kernel,
spdisp = spdisp, dMat = dMat, offset = offset4fit, dispersion = dispersion, control = control)
betas <- fit.gwer[[1]]
#std.error <- fit.gwer[[8]]
#p.values <- fit.gwer[[5]]
if(spdisp == 'local' || spdisp == 'global')
dispersion <- fit.gwer[[4]]
if(hatmatrix) {
Shat <- fit.gwer[[2]]
C <- fit.gwer[[3]]
H <- fit.gwer[[6]]
Haux <- fit.gwer[[7]]
idm <- diag(var.n)
for(i in 1:var.n)
for(j in 1:dp.n)
{
S.arrays[i, j, ] <- X1[j, i]*(idm[i, ]%*%C[j, , ])
H.arrays[i, j, ] <- X1[j, i]*(idm[i, ]%*%Haux[j, , ])
}
}
cat("------ The end for calculating the initial beta0 ------\n")
cat("------ Select the optimum bandwidths for each independent variable via ", approach, " aproach ------\n")
iteration <-0
bws.vars <- bws0
bws.change.NO <- numeric(var.n)
criterion.val <- 10000000
resid.i <- Y - (X1*betas)%*%matrix(1, ncol(X1), 1)#####gw.fitted(X1, betas)
RSS0 <- sum(resid.i^2)
RSS1 <- 0
RSS.vals <- c(RSS0, RSS1, criterion.val)
cat("***** The back-fitting process for model calibration with bandwiths selected *****\n")
# gweights <- matrix(0,n,n) ; local.fitted <- matrix(0,n,n) ; sum.w <- numeric(n)# ; resid.ord <- matrix(0,n,1)
#
# if(spdisp){
# dispersion.gwer <- numeric(n)
# gwr.b <- matrix(nrow = nobs, ncol = ncol(X)+1)
# stderror <- matrix(0,n,p+1) ; zvalue <- matrix(0,n,p) ; pvalue <- matrix(0,n,p)
# colnames(gwr.b) <- c(colnames(X), "dispersion")
# colnames(stderror) <- c(paste(colnames(X),rep(".se",p), sep = ""), "dispersion.se")
# } else {
# gwr.b <- matrix(nrow = nobs, ncol = ncol(X))
# stderror <- matrix(0,n,p) ; zvalue <- matrix(0,n,p) ; pvalue <- matrix(0,n,p)
# colnames(gwr.b) <- c(colnames(X))
# colnames(stderror) <- paste(colnames(X),rep(".se",p), sep = "")
# }
# colnames(zvalue) <- colnames(pvalue) <- c(colnames(X))
# Iterative process #
while((iteration < max.iterations) && criterion.val > threshold) {
cat(" Iteration ", iteration + 1, ":\n")
for(i in 1:var.n) {
dMat <- dMats[[i]]
f.i <- betas[, i]*X1[, i]
X.i <- matrix(X1[, i], ncol = 1)
colnames(X.i) <- colnames(X1)[i]
Y.i <- resid.i + f.i
if(bw.seled[i])
bw.i <- bws0[i]
else {
cat("Now select an optimum bandwidth for the variable: ", InDevars[i], "\n")
bw.i <- bw.gwer1(X.i, Y.i, dp.locat = dp.locat, approach = approach, kernel = kernel, adaptive = adaptive,
dispersion = dispersion, dMat = dMat, family = family, verbose = verbose, nlower = nlower)
cat("The newly selected bandwidth for variable ", InDevars[i])
cat(" is: ", bw.i, "\n")
cat("The bandwidth used in the last iteration is: ", bws0[i])
cat(" and the difference between these two bandwidths is: ", abs(bw.i - bws0[i]), "\n")
if (abs(bw.i - bws0[i]) > bws.thresholds[i]) {
cat("The bandwidth for variable ", InDevars[i])
cat(" will be continually selected in the next iteration.\n")
bws.change.NO[i] <- 0
}
else {
bws.change.NO[i] <- bws.change.NO[i] + 1
if(bws.change.NO[i] < bws.reOpts) {
cat("The bandwidth for variable ", InDevars[i])
cat(" seems to be converged for ", bws.change.NO[i], " times.")
cat("It will be continually optimized in the next ", bws.reOpts-bws.change.NO[i], " times\n")
}
else {
cat("The bandwidth for variable ", InDevars[i])
cat(" seems to be converged and will be kept the same in the following iterations.\n")
bw.seled[i] <- T
}
}
}
bws0[i] <- bw.i
#res <- gwr.q2(matrix(X1[,i], ncol=1), y.i, dp.locat, adaptive=adaptive, hatmatrix = hatmatrix,bw=bw.i, kernel=kernel,dMat=dMat)
fit.i <- gwer.mfit(X.i, Y.i, family = family, loc = dp.locat, adaptive = adaptive, hatmatrix = hatmatrix,
bw = bw.i, kernel = kernel, dMat = dMat, spdisp = spdisp, offset = offset4fit,
dispersion = dispersion, control = control)
beta.i <- fit.i[[1]]
# std.error.i <- fit.i[[8]]
# p.values.i <- fit.i[[5]]
# dxs <- spDistsN1(coords, fit.points[i, ], longlat = longlat)
# if (any(!is.finite(dxs)))
# dxs[which(!is.finite(dxs))] <- .Machine$double.xmax/2
# w.i <- gweight(dxs^2, bandwidth[i])
# if (any(w.i < 0 | is.na(w.i)))
# stop(paste("Invalid weights for i:", i))
# fit.i <- elliptical.fitter(X = X, Y = Y, gweights = w.i, offset = offset4fit,
# family = family, dispersion = dispersion,
# maxit = control$maxit, epsilon = control$epsilon,
# trace = control$trace, ...)
# sum.w[i] <- sum(w.i)
# v_fitteds[i] <- fit.i$fitted.values[i]
# if(spdisp){
# dispersion.gwer[i] <- fit.i$dispersion
# gwr.b[i, ] <- c(coefficients(fit.i), dispersion.gwer[i])
# } else{
# gwr.b[i, ] <- coefficients(fit.i)
# }
# if (!fp.given && hatmatrix) {
# if(spdisp){
# stderror[i, ] <- c(rowlen[1:p] * sqrt(fit.i$dispersion/fit.i$scale), sqrt(4*fit.i$dispersion^2/(sum(fit.i$gweights)*fit.i$scaledispersion)))
# zvalue[i, ] <- c(gwr.b[i, 1:p])/stderror[i, 1:p]
# pvalue[i, ] <- 2 * pnorm(-abs(zvalue[i, ]))
# } else {
# stderror[i, ] <- rowlen[1:p] * sqrt(fit.i$dispersion/fit.i$scale)
# zvalue[i, ] <- c(gwr.b[i, ])/stderror[i, ]
# pvalue[i, ] <- 2 * pnorm(-abs(zvalue[i, ]))
# }
# Hat[i,] <- X[i,] %*% solve(t(X) %*% diag(w.i) %*% X) %*% t(X) %*% diag(w.i)
# }
if(spdisp == 'multi'){
disp.mult[, i] <- fit.i[[4]]
dispersion <- apply(disp.mult, 2, mean)
}
if(hatmatrix)
{
Si <- fit.i[[2]]
S.arrayi <- S.arrays[i,,]
S.arrays[i,,] <- Si%*%S.arrayi + Si - Si%*%Shat
Shat <- Shat - S.arrayi + S.arrays[i,,]
Hi <- fit.i[[6]]
H.arrayi <- H.arrays[i,,]
H.arrays[i,,] <- Hi%*%H.arrayi + Hi - Hi%*%H
H <- H - H.arrayi + H.arrays[i,,]
}
betas[, i] <- beta.i
#std.error[, i] <- std.error.i
#p.values[, i] <- p.values.i/(sum(diag(S.arrays[i,,]))/var.n)
resid.i <- Y - (X1*betas)%*%matrix(1, ncol(X1), 1)
#resid.i <- Y - gw.fitted(X1, betas)
ms.gweights[i,,] <- fit.i[[9]]
}
bws.vars <- rbind(bws.vars, bws0)
RSS1 <- sum((Y - (X1*betas)%*%matrix(1, ncol(X1), 1))^2)
#RSS1 <- sum((Y - gw.fitted(X1, betas))^2)
if(criterion=="CVR") {
criterion.val <- abs(RSS1-RSS0)
cat(" Iteration ", iteration, "the change value of RSS (CVR) is: ", criterion.val,"\n")
}
else {
criterion.val <- sqrt(abs(RSS1-RSS0)/RSS1)
cat(" Iteration ", iteration + 1, "the differential change value of RSS (dCVR) is: ", criterion.val,"\n")
}
RSS0 <- RSS1
cat("----------End of Iteration ", iteration + 1, "----------\n")
RSS.vals <- rbind(RSS.vals, c(RSS0, RSS1, criterion.val))
iteration <- iteration + 1
}
# Output #
local.fitted <- betas %*% t(X1)
yhat <- (X1*betas)%*%matrix(1, ncol(X1), 1)
residual <- Y - yhat
dispersion.gwer <- fit.gwer[[4]]
RSS.gw <- RSS1
yss.g <- sum((y - mean(y))^2)
R2.val <- 1-RSS.gw/yss.g
R2adj <- NA
AIC <- NA ; AICc <- NA ; BIC <- NA
if(hatmatrix) {
scalevariance <- family$g4(res, df = family$df,
r = family$r, s = family$s, alpha = family$alpha,
mp = family$mp, epsi = family$epsi, sigmap = family$sigmap,
k = family$k)
D.phi <- diag(dispersion.gwer) ; alpha.pv <- rep(1, var.n)
std.error <- z.value <- p.values <- matrix(nrow=dp.n, ncol=var.n)
for(i in 1:var.n) {
C.i <- solve(diag(X1[, i]))%*%S.arrays[i,,]
var.beta.i <- C.i%*%D.phi%*%t(C.i)*scalevariance
std.error[, i] <- sqrt(diag(var.beta.i))
z.value[, i] <- c(betas[, i])/std.error[, i]
p.values.i <- 2*pnorm(-abs(z.value[, i]))
p.values[, i] <- p.values.i#/(sum(diag(S.arrays[i,,]))/var.n)
alpha.pv[i] <- (sum(diag(S.arrays[i,,]))/var.n)
}
nu1 <- sum(diag(Shat))
nu2 <- sum(diag(Shat^2))
res <- (Y - yhat)/dispersion.gwer
rpearson <- res/sqrt(scalevariance)
#H1 <- (1/(scalevariance * scale)) * H
#varr <- scalevariance * (1 - diag(H1))
#rstand <- res/sqrt(varr)
if (charmatch(dist, "Normal", F)) {
dist.y <- pnorm(Y, yhat, dispersion.gwer)
}
else if (charmatch(dist, "Cauchy", F)) {
dist.y <- pcauchy(Y, yhat, dispersion.gwer)
}
else if (charmatch(dist, "Student", F)) {
dist.y <- pt(res, family$df)
}
else if (charmatch(dist, "Gstudent", F)) {
dist.y <- pgstudent(res, family$s, family$r)
}
else if (charmatch(dist, "LogisI", F)) {
stop(paste("not implemented yet"))
dist.y <- plogisI(Y, yhat, dispersion.gwer)
}
else if (charmatch(dist, "LogisII", F)) {
dist.y <- plogisII(res)
}
else if (charmatch(dist, "Glogis", F)) {
stop(paste("not implement yet"))
dist.y <- NULL#pglogis(res, family$alpha, family$mp)
}
else if (charmatch(dist, "Cnormal", F)) {
stop(paste("not implemented yet"))
dist.y <- NULL#pcnormal(res, family$epsi, family$sigmap)
}
else if (charmatch(dist, "Powerexp", F)) {
dist.y <- ppowerexp(res, family$k)
}
rquant <- qnorm(dist.y, 0, 1)
logLik <- -0.5 * sum(log(dispersion.gwer)) + sum(family$g0(res, df = family$df, s = family$s, r = family$r,
alpha = family$alpha, mp = family$mp, epsi = family$epsi,
sigmap = family$sigmap, k = family$k))
edf <- dp.n - 2*nu1 + nu2
AIC <- 2*nu1 - 2*logLik
AICc <- -2*logLik + (dp.n*(dp.n + nu1))/(dp.n-2-nu1)
BIC <- log(dp.n)*nu1 - 2*logLik
R2.adj <- 1-(1-R2.val)*(dp.n-1)/(edf-1)
}
GW.diagnostic <- list(RSS.gw = RSS.gw, logLik = logLik, AIC = AIC, AICc = AICc, BIC = BIC, Hat = Shat, R2.val = R2.val, R2.adj = R2.adj)
if(!is.na(idx1) && n.cent>=1) {
idx.cent <- which(predictor.centered)
betas.cent <- c()
for(i in 1:n.cent)
betas.cent <- cbind(betas.cent, betas[,idx.cent[i]+1]*predictors.centered.means[i])
beta0 <- betas[,idx1] - apply(betas.cent, 1, sum)
betas[,idx1] <- beta0
}
vdgwer.df <- data.frame(betas, yhat, residual)
colnames(vdgwer.df) <- c(colnames(X), "yhat", "residual")
griddedObj <- F
if (is(regression.points, "Spatial"))
{
if (is(regression.points, "SpatialPolygonsDataFrame"))
{
polygons<-polygons(regression.points)
SDF <-SpatialPolygonsDataFrame(Sr=polygons, data=vdgwer.df,match.ID=F)
}
else
{
griddedObj <- gridded(regression.points)
SDF <- SpatialPointsDataFrame(coords=dp.locat, data=vdgwer.df, proj4string=CRS(p4s), match.ID=F)
gridded(SDF) <- griddedObj
}
}
else
SDF <- SpatialPointsDataFrame(coords=dp.locat, data=vdgwer.df, proj4string=CRS(p4s), match.ID=F)
timings[["stop"]] <- Sys.time()
GW.arguments <- list(formula = formula, criterion = criterion, bws = bws0, alpha.pv = alpha.pv, kernel = kernel, adaptive = adaptive, hatmatrix = hatmatrix)
GW.residual <- list(ordinal = residual, response = res, pearson = rpearson, quantile = rquant)
z <- list(SDF = SDF, coef = betas, se = std.error, pv = p.values, dispersion = dispersion.gwer, gweights = ms.gweights, fitted = yhat, flm = local.fitted, lm = fit,
bandwidth = bws.vars, GW.residual = GW.residual, GW.arguments = GW.arguments, GW.diagnostic = GW.diagnostic, family = fit$family, timings = timings,
hatmatrix = hatmatrix, this.call = this.call)
class(z) <- "multiscalegwer"
invisible(z)
}
#--------------------#
# Estimation Process #
#--------------------#
gwer.mfit <- function(X, Y, family, loc, adaptive = FALSE, hatmatrix, bw=sqrt(var(loc[,1])+var(loc[,2])),
kernel, p, theta, longlat, dMat, wt2=rep(1,nrow(loc)), spdisp, offset, dispersion, control)
{
if (missing(dMat))
DM.given <- F
else
DM.given <- T
dp.n <- nrow(loc) ; var.n <- ncol(X)
gweights <- matrix(nrow=dp.n, ncol=dp.n)
gwr.b <- matrix(nrow=dp.n, ncol=var.n) ; dispersion.gwer <- rep(0, dp.n)
pvalue <- zvalue <- stderror <- matrix(nrow=dp.n, ncol=var.n)
S <- matrix(nrow=dp.n, ncol=dp.n)
C <- array(dim=c(dp.n, var.n, dp.n))
H <- matrix(nrow=dp.n, ncol=dp.n)
Haux <- array(dim=c(dp.n, var.n, dp.n))
for (i in 1:dp.n)
{
if(DM.given)
dist.vi <- dMat[,i]
else
dist.vi <- gw.dist(loc, focus=i, p, theta, longlat)
w.i <- gw.weight(dist.vi, bw, kernel, adaptive)
fit.i <- gwer.fit(X = X, Y = Y, gweights = w.i, offset = offset,
family = family, dispersion = dispersion[i],
maxit = control$maxit, epsilon = control$epsilon,
trace = control$trace)
#gw.resi <- gw_reg(x,y,as.vector(W.i*wt2),hatmatrix=hatmatrix,i)
#betas[i,] <- gw.resi[[1]]
#if(spdisp == 'local' || spdisp == 'multiscale'){
# dispersion.gwer[i] <- fit.i$dispersion
# gwr.b[i, ] <- coefficients(fit.i)#c(coefficients(fit.i), dispersion.gwer[i])
#} else{
# dispersion.gwer[i] <- fit.i$dispersion
# gwr.b[i, ] <- coefficients(fit.i)
#}
dispersion.gwer[i] <- fit.i$dispersion
gwr.b[i, ] <- coefficients(fit.i)
gweights[i,] <- fit.i$gweights
R <- fit.i$R[(1:var.n), (1:var.n)]
covun <- solve(qr(R))
rowlen <- sqrt(diag(covun))
if(hatmatrix){
stderror[i, ] <- rowlen[1:var.n] * sqrt(fit.i$dispersion/fit.i$scale)
zvalue[i, ] <- c(gwr.b[i, ])/stderror[i, ]
pvalue[i, ] <- 2 * pnorm(-abs(zvalue[i, ]))
S[i,] <- fit.i$Hat[i, ]
C[i,,] <- fit.i$Ci
H[i,] <- fit.i$H[i, ]
Haux[i,,] <- fit.i$Haux
#S[i,]<-gw.resi[[2]]
#C[i,,]<-gw.resi[[3]]
}
#fitteds[i] <- fit.i$fitted.values[i]
}
colnames(gwr.b) <- colnames(X)
fit <- list(gwr.b, S, C, dispersion.gwer, pvalue, H, Haux, stderror, gweights)
fit
}
#---------------------#
# Bandwidth Selection #
#---------------------#
bw.gwer1 <- function(x, y, dp.locat, approach="AIC", kernel="gaussian", adaptive = FALSE, dispersion, dMat, family, verbose=F, nlower = 10)
{
dp.n <- nrow(dp.locat)
if(adaptive)
{
upper <- dp.n
lower <- nlower
}
else
{
upper<-range(dMat)[2]
lower<-upper/5000
}
#Select the bandwidth by golden selection
bw<-NA
if (approach=="cv"||approach=="CV")
bw <- gold2(gwer.cv, lower, upper, adapt.bw=adaptive, x, y, kernel, adaptive, dispersion, dp.locat, dMat=dMat, family = family, verbose=verbose)
else if (approach=="aic"||approach=="AIC"||approach=="AICc")
bw <- gold2(gwer.aic, lower, upper, adapt.bw=adaptive, x, y, kernel, adaptive, dispersion, dp.locat, dMat=dMat, family = family, verbose=verbose)
else if (approach=="mi"||approach=="MI")
bw <- gold2(gwer.mi, lower, upper, adapt.bw=adaptive, x, y, kernel, adaptive, dispersion, dp.locat, dMat=dMat, family = family, verbose=verbose)
bw
}
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.