Nothing
#
# fields is a package for analysis of spatial data written for
# the R software environment.
# Copyright (C) 2024 Colorado School of Mines
# 1500 Illinois St., Golden, CO 80401
# Contact: Douglas Nychka, douglasnychka@gmail.com,
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with the R software environment if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
# or see http://www.r-project.org/Licenses/GPL-2
##END HEADER
"vgram" <- function(loc, y, id = NULL, d = NULL, lon.lat = FALSE,
dmax = NULL, N = NULL, breaks = NULL, prettyBins=FALSE,
type=c("variogram", "covariogram", "correlogram")) {
type=match.arg(type)
#
# if prettyBins is FALSE then generate exactly N breaks and so N-1 bins.
# otherwise number of breaks is at the mercy of the pretty function
# and may be N-1 or something else!
#
# coerce to matrix
y <- cbind(y)
# if nearest neighbor indices are missing create all possible pairs.
if (is.null(id)) {
n <- nrow(loc)
is = rep(1:n, n)
js = rep(1:n, rep(n, n))
ind <- is > js
id <- cbind(is, js)[ind, ]
}
# if distances are missing calculate these
if (is.null(d)) {
loc <- as.matrix(loc)
if (lon.lat) {
d <- rdist.earth.vec(loc[id[,1],], loc[id[,2],]) #we want result in miles, not meters
}
else {
d <- rdist.vec(loc[id[,1],], loc[id[,2],])
}
}
# normalize columns to create correlogram, if necessary
#
if(type == "correlogram") {
tau = apply(y, 2, sd, na.rm=TRUE)
y = sweep(y, 2, (1/tau), FUN="*")
}
# center the columns by their mean and get row means if y is a matrix
#
colMeans <- apply(y, 2, mean, na.rm=TRUE)
yCntr = sweep(y, 2, colMeans)
y1Cntr = yCntr[id[,1],]
y2Cntr = yCntr[id[,2],]
if(type == "variogram") {
vg <- 0.5 * rowMeans(cbind((y1Cntr - y2Cntr)^2),
na.rm = TRUE)
}
else {
vg <- rowMeans(cbind(y1Cntr * y2Cntr),
na.rm = TRUE)
}
#
#information for returned object
#
call <- match.call()
if (is.null(dmax)) {
dmax <- max(d)
}
od <- order(d)
d <- d[od]
vg <- vg[od]
ind <- d <= dmax & !is.na(vg)
## add a binned variogram if breaks are supplied
out <- list(d = d[ind], vgram = vg[ind], call = call, type=type)
if (!is.null(breaks) | !is.null(N)) {
out <- c(out, stats.bin(d[ind], vg[ind], N = N, breaks = breaks,
prettyBins=prettyBins))
}
class(out) = c("vgram", class(out))
out
}
#calculating cross-covariogram and cross-correlogram (cross-covariance and
#cross-correlation)
crossCoVGram = function(loc1, loc2, y1, y2, id = NULL, d = NULL, lon.lat = FALSE,
dmax = NULL, N = NULL, breaks = NULL,
type=c("cross-covariogram", "cross-correlogram"),
prettyBins=FALSE) {
type=match.arg(type)
# coerce to matrix
y1 <- cbind(y1)
y2 <- cbind(y2)
# if nearest neighbor indices are missing create all possible pairs.
if (is.null(id)) {
n1 <- nrow(loc1)
n2 <- nrow(loc2)
id <- cbind(rep(1:n1, n2), rep(1:n2, rep(n1, n2)))
}
# if distances are missing calculate these
if (is.null(d)) {
loc1 <- as.matrix(loc1)
loc2 <- as.matrix(loc2)
if (lon.lat) {
d <- rdist.earth.vec(loc1[id[,1],], loc2[id[,2],]) #we want result in miles, not meters
}
else {
d <- rdist.vec(loc1[id[,1],], loc2[id[,2],])
}
}
#
# calculating covariogram will center the columns by their mean and get row means if y is a matrix
#
colMeans1 <- apply(y1, 2, mean, na.rm=TRUE)
colMeans2 <- apply(y2, 2, mean, na.rm=TRUE)
y1Cntr = sweep(data.matrix(y1), 2, colMeans1) # subtract the column means
y2Cntr = sweep(data.matrix(y2), 2, colMeans2) # subtract the column means
#
# normalize to create cross-correlogram, if necessary
#
if(type == "cross-correlogram") {
tau1 = apply(y1Cntr, 2, sd, na.rm=TRUE)
tau2 = apply(y2Cntr, 2, sd, na.rm=TRUE)
y1Cntr = sweep(y1Cntr, 2, 1/tau1, FUN="*")
y2Cntr = sweep(y2Cntr, 2, 1/tau2, FUN="*")
}
#
# calculate covariance for the given points
#
y1Cntr = y1Cntr[id[,1],]
y2Cntr = y2Cntr[id[,2],]
vg <- rowMeans(cbind(y1Cntr*y2Cntr), na.rm = TRUE)
#
#information for returned object
#
call <- match.call()
if (is.null(dmax)) {
dmax <- max(d)
}
od <- order(d)
d <- d[od]
vg <- vg[od]
ind <- d <= dmax & !is.na(vg)
## add a binned variogram if breaks are supplied
out <- list(d = d[ind], vgram = vg[ind], call = call, type=type)
if (!is.null(breaks) | !is.null(N)) {
out <- c(out, stats.bin(d[ind], vg[ind], N = N, breaks = breaks,
prettyBins=prettyBins))
}
class(out) = c("vgram", class(out))
out
}
#plot only the line of the empirical variogram, where the y coordinates of the line are
#at the means of the bins
plot.vgram = function(x, N=10, breaks = pretty(x$d, N, eps.correct = 1), add=FALSE, ...) {
otherArgs = list(...)
type=x$type
#set y axis label if not set by user
if(is.null(otherArgs$ylab)) {
if(type=="variogram")
otherArgs$ylab = "Variance"
else if(type == "covariogram" || type=="cross-covariogram")
otherArgs$ylab = "Covariance"
else if(type == "correlogram" || type=="cross-correlogram")
otherArgs$ylab = "Correlation"
else
stop("vgram 'type' argument must be either 'variogram', 'covariogram', 'correlogram', 'cross-covariogram', or 'cross-correlogram'")
}
#set x axis label if not set by user
if(is.null(otherArgs$xlab))
otherArgs$xlab = "Distance"
#set plot title if not set by user
if(is.null(otherArgs$main)) {
if(type=="variogram")
otherArgs$main = "Empirical Variogram"
else if(type=="covariogram")
otherArgs$main = "Empirical Covariogram"
else if(type=="correlogram")
otherArgs$main = "Empirical Correlogram"
else if(type=="cross-covariogram")
otherArgs$main = "Empirical Cross-Covariogram"
else if(type=="cross-correlogram")
otherArgs$main = "Empirical Cross-Correlogram"
else
stop("vgram 'type' argument must be either 'variogram', 'covariogram', 'correlogram', 'cross-covariogram', or 'cross-correlogram'")
}
#set ylim for correlogram if not set by user
if(is.null(otherArgs$ylim)) {
if(type == "correlogram" || type=="cross-correlogram")
otherArgs$ylim = c(-1, 1)
}
#set line type if not set by user
if(is.null(otherArgs$type))
otherArgs$type = "o"
#get bin data
dat = getVGMean(x, breaks=breaks)
#get bin centers versus bin means
centers = dat$centers
ys = dat$ys
#remove NAs
notNas = !is.na(ys)
centers = centers[notNas]
ys = ys[notNas]
#plot
if(!add)
do.call("plot", c(list(centers, ys), otherArgs))
else
do.call("lines", c(list(centers, ys), otherArgs))
}
"boxplotVGram" = function(x, N=10, breaks = pretty(x$d, N, eps.correct = 1), plot=TRUE,
plot.args=NULL, ...) {
dists = x$d
type=x$type
if(type == "variogram")
y = sqrt(x$vgram)
else
y = x$vgram
otherArgs = list(...)
#set y axis label if not set by user
if(is.null(otherArgs$ylab)) {
if(type=="variogram")
otherArgs$ylab = "sqrt(Variance)"
else if(type == "covariogram" || type=="cross-covariogram")
otherArgs$ylab = "Covariance"
else if(type == "correlogram" || type=="cross-correlogram")
otherArgs$ylab = "Correlation"
else
stop("vgram 'type' argument must be either 'variogram', 'covariogram', 'correlogram', 'cross-covariogram', or 'cross-correlogram'")
}
#set x axis label if not set by user
if(is.null(otherArgs$xlab))
otherArgs$xlab = "Distance"
#set plot title if not set by user
if(is.null(otherArgs$main)) {
if(type=="variogram")
otherArgs$main = "Empirical Variogram (square root scale) "
else if(type=="covariogram")
otherArgs$main = "Empirical Covariogram"
else if(type=="correlogram")
otherArgs$main = "Empirical Correlogram"
else if(type=="cross-covariogram")
otherArgs$main = "Empirical Cross-Covariogram"
else if(type=="cross-correlogram")
otherArgs$main = "Empirical Cross-Correlogram"
else
stop("vgram 'type' argument must be either 'variogram', 'covariogram', 'correlogram', 'cross-covariogram', or 'cross-correlogram'")
}
#set ylim for correlogram if not set by user
if(is.null(otherArgs$ylim)) {
if(type == "correlogram" || type=="cross-correlogram")
otherArgs$ylim = c(-1, 1)
}
#make boxplot
bplot = do.call("bplot.xy", c(list(x=dists, y=y, N=N, breaks=breaks, plot=plot), otherArgs))
#return bplot.xy statistics if plot==FALSE
if(!plot)
return(bplot)
# #plot bin means with plot parameters given in plot.args (with defaults to look pretty)
# plot.args$x=x
# plot.args$add=TRUE
# plot.args$breaks=breaks
# if(is.null(plot.args$col))
# plot.args$col = "red"
# if(is.null(plot.args$type))
# plot.args$type = "p"
# do.call("plot.vgram", plot.args)
}
# Returns the variogram bin centers and means
getVGMean = function(x, N = 10,
breaks = pretty(x$d, N, eps.correct = 1))
{
# Can calculate mean or other statistical functions of the values in the bins
VGstat = function(VG, minD=-Inf, maxD=Inf, statFun="mean", ...) {
ind = (VG$d > minD) & (VG$d < maxD)
do.call(statFun, c(list(VG$vgram[ind]), list(...)))
}
#helper function to get mean from any single bin
meansFromBreak = function(breakBounds = c(-Inf, Inf)) {
VGstat(x, minD=breakBounds[1], maxD=breakBounds[2], na.rm=TRUE)
}
#apply helper function to all bins
lowBreaks = breaks
highBreaks = c(breaks[2:length(breaks)], Inf)
breakBounds = cbind(lowBreaks, highBreaks)
centers = apply(breakBounds, 1, mean, na.rm=TRUE)
ys = apply(breakBounds, 1, meansFromBreak)
#take square root if variogram
# if(x$type == "variogram")
# ys=sqrt(ys)
return(list(centers=centers, ys=ys, type=x$type))
}
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.