library(sp)
library(gstat)
library(ggplot2)
library(maptools)
## Checking rgeos availability: FALSE
## Note: when rgeos is not available, polygon geometry computations in maptools depend on gpclib,
## which has a restricted licence. It is disabled by default;
## to enable gpclib, type gpclibPermit()
library(raster)
load("wUSPrec_Bnd.Rdata")
summary(wUSPrec)
## Object of class SpatialPointsDataFrame
## Coordinates:
## min max
## long -302251.8 381330.4
## lat -422252.6 556846.7
## Is projected: TRUE
## proj4string :
## [+proj=aea +lat_1=41 +lat_2=47 +lat_0=44 +lon_0=-120 +x_0=0 +y_0=0
## +ellps=GRS80 +datum=NAD83 +units=m +no_defs +towgs84=0,0,0]
## Number of points: 113
## Data attributes:
## prec
## Min. : 23.69
## 1st Qu.: 40.88
## Median : 60.92
## Mean : 75.00
## 3rd Qu.: 97.62
## Max. :272.76
sp_map <- fortify(wUSBoundary)
## Regions defined for each Polygons
wUSPrec.df <- data.frame(wUSPrec)
gg <- ggplot()
gg <- gg + geom_map(data=sp_map,map=sp_map,
aes(x=long, y=lat, map_id=id),
fill= "white",color="black")
gg <- gg + geom_point(data=wUSPrec.df, aes(x=long, y=lat, size=prec),
color="orange")
gg <- gg + scale_size(breaks=seq(0,300,by=50))
gg <- gg + labs(x=NULL, y=NULL)
gg <- gg + theme(panel.grid=element_blank(), panel.border=element_blank())
gg <- gg + theme(axis.ticks=element_blank(), axis.text=element_blank())
gg <- gg + theme(legend.position="top")
gg
e <- extent(wUSPrec)
wUSPrec.grid <- raster(e)
proj4string(wUSPrec.grid) <- proj4string(wUSPrec)
res(wUSPrec.grid) <- c(1e4,1e4)
wUSPrec.grid <- as(wUSPrec.grid,"SpatialPointsDataFrame")
plot(wUSPrec.grid,col="grey")
points(wUSPrec,pch=20,col="red")
Here is a grid map of the points overlaying the entire area. Now I can interpolate points over the rest of the grid.
Now I’ll create a spatial points data frame of the IDW with a power of 2.5.
precIDW1 <- idw(formula=prec~1,locations=wUSPrec,newdata=wUSPrec.grid,idp=2.5)
## [inverse distance weighted interpolation]
head(precIDW1@data)
## var1.pred var1.var
## 1 94.97661 NA
## 2 94.77424 NA
## 3 94.34023 NA
## 4 93.26673 NA
## 5 91.69603 NA
## 6 90.97853 NA
spplot(precIDW1,"var1.pred",main="p=2.5")
precIDW3.5 <- idw(formula=prec~1,locations=wUSPrec,newdata=wUSPrec.grid,idp=3.5)
## [inverse distance weighted interpolation]
spplot(precIDW3.5,"var1.pred",main="p=3.5")
precIDW2 <- idw(formula=prec~1,locations=wUSPrec,newdata=wUSPrec.grid,idp=1)
## [inverse distance weighted interpolation]
spplot(precIDW2,"var1.pred", main="p=1")
As the value of p shrinks, more distant points have more of an effect on the interpolated points. A highter p means that closer points have a greater weight. Thus IDW with a low p tend to produce more accurate plots with less error. I guess the “right” value may be somewhat objective…but should be somewhere around the default that R uses of 2.
show.vgms(max=1500, models = c("Exp", "Mat", "Gau", "Sph"), sill=15, nugget = 5, range=1000)
This looks like the spherical model is best. I’ll stick with that.
precvar<- variogram(prec~1, wUSPrec)
summary(precvar)
## np dist gamma dir.hor dir.ver
## Min. : 14.0 Min. : 19101 Min. : 690.9 Min. :0 Min. :0
## 1st Qu.:157.0 1st Qu.:106259 1st Qu.:1380.6 1st Qu.:0 1st Qu.:0
## Median :239.0 Median :199112 Median :1901.7 Median :0 Median :0
## Mean :199.6 Mean :199504 Mean :1691.5 Mean :0 Mean :0
## 3rd Qu.:259.5 3rd Qu.:291831 3rd Qu.:1981.7 3rd Qu.:0 3rd Qu.:0
## Max. :291.0 Max. :384270 Max. :2327.3 Max. :0 Max. :0
## id
## var1:15
##
##
##
##
##
plot(precvar,pch=20,cex=1.5,col="black",
ylab=expression("Semivariance ("*gamma*")"),
xlab="Distance (m)", main = "Summer precipitation (mm)")
The variogram shows spatial autocorrelation out to about 2.5 e05m (250km). Now, let’s fit the variogram model. I’m using a sill of 2500, a range of 2.5e+05, and a nugget of 600 to start things off.
sph.model <- vgm(psill=2500, model="Sph", range=2.5e+05, nugget=600)
sph.fit <- fit.variogram(object = precvar, model = sph.model)
plot(precvar,pch=20,cex=1.5,col="black",
ylab=expression("Semivariance ("*gamma*")"),
xlab="Distance (m)", main = "Summer precipitation (mm)",model=sph.fit)
sph.fit
## model psill range
## 1 Nug 564.7154 0.0
## 2 Sph 1479.0279 251499.7
This shows the nugget at 564, the sill at 1,479, and the range at 251,500
Here’s an exponential model just for kicks…this model is more of a gradual curve and doesn’t really highlight the sill as well as the spherical model.
sph.model <- vgm(psill=2500, model="Exp", range=2.5e+05, nugget=600)
sph.fit <- fit.variogram(object = precvar, model = sph.model)
plot(precvar,pch=20,cex=1.5,col="black",
ylab=expression("Semivariance ("*gamma*")"),
xlab="Distance (m)", main = "Summer precipitation (mm)",model=sph.fit)
Let’s get the weights now from the spherial model…
precsph <- krige(prec~1, wUSPrec, wUSPrec.grid, model = sph.fit)
## [using ordinary kriging]
spplot(precsph,"var1.pred")
library(automap)
precvar <- autofitVariogram(prec~1,wUSPrec)
plot(precvar)
The automatic kriging shows the sill at 2025, the range at 1.13e+05, and the nugget at 538. These numbers are definitely different than the by hand version of kriging.
Now I’ll krige a surface automatically…
precKrig <- autoKrige(prec~1, wUSPrec, wUSPrec.grid)
## [using ordinary kriging]
plot(precKrig)
I see high error in those areas with few data points. But, I’m not sure how to go about solving this issue. Maybe adjust the neighborhood of points?