R Spatial Analysis using SP

33
Applied Spatial Data Analysis using R Thomas Jagger Department of Geography Florida State University Denver R User Group Meeting October 19, 2010 with special thanks to Roger Bivand: http://www.asdar-book.org

description

This is an introduction to the R SP package.

Transcript of R Spatial Analysis using SP

Page 1: R Spatial Analysis using SP

Applied Spatial Data Analysis using R

Thomas JaggerDepartment of Geography

Florida State University

Denver R User Group MeetingOctober 19, 2010

with special thanks to

Roger Bivand: http://www.asdar-book.org

Page 2: R Spatial Analysis using SP

TopicsTopics

1. Spatial objects in the “sp” Package• Points, Lines, Polygons, Pixels and Grids

2. The S4 Framework • Classes, slots, methods, inheritance

3. How to create, convert, explore and manipulate “sp” spatial objects.

4. Example: Analyzing tornado data using the R “sp” package.

Page 3: R Spatial Analysis using SP

Sources of Information

Spatial data:1.http://cran.r-project.org/web/views/Spatial.html2.http://r-spatial.sourceforge.net/ 3.vignette("sp")4.Rnews: http://cran.r-project.org/doc/Rnews/Rnews_2005-2.pdf5.Applied Spatial Data Analysis with R6.http://spatial-analyst.net wiki

Plotting 1.http://r-spatial.sourceforge.net/gallery/2.Figures for ASDAR Tornado data from the Storm Prediction Center (SPC)Slides on Spatial Data Courtesy of Roger Bivand http://spatial-analyst.net/Rosgeo/sites/default/files/plasencia_monday_R.pdf

Page 4: R Spatial Analysis using SP

Object Framework

•To begin with, all contributed packages for handling spatial data in R had different representations of the data. •This made it difficult to exchange data both within R between packages, and between R and external file formats and applications.•The result has been an attempt to develop shared classes to represent spatial data in R, allowing some shared methods and many-to-one, one-to-many conversions.•Roger Bivand and his collaborators chose to use new-style classes to represent spatial data and they are confident that this choice was justified.

Page 5: R Spatial Analysis using SP

Spatial Points• The most basic spatial data object is a point, which may have

2 or 3 dimensions

• Consists of a single coordinate, or a set of such coordinates.

• To define a SpatialPoints object; coordinates should be of mode double and will be promoted if not already.

• The points in a SpatialPoints object may be associated with a row of attributes to create a SpatialPointsDataFrame object

• The coordinates and attributes may, but do not have to be keyed to each other using ID value.

• Objects can be manipulated as a data frame though they appear as GIS objects i.e. features with attributes.

• Spatial objects rarely created from scratch, rather they are created by promoting another object such as a data frame into a SpatialPointsDataFrame object.

Page 6: R Spatial Analysis using SP

Spatial Points Diagram

• The boxes are the object classes definition– Blue is the class name– White represents slots within each class– Arrows show inheritance

Page 7: R Spatial Analysis using SP

Spatial Points Example:Colorado Tornado Touchdowns

require(sp)download.file("http://www.spc.noaa.gov/gis/svrgis/

Tornado_touchdown_points.zip","Tornado_touchdown_points.zip",mode="wb")

require(maptools)Tornado<-

read.dbf(zip.file.extract("Tornado_touchdown_points.dbf",zip="Tornado_touchdown_points.zip"))

TornadoContUS<-subset(Tornado, !(FIPS %in% c(2,66,15,60,72,78,99)) & SLAT !=0 & SG ==1 & FSCALE >=0)

ColTornado<-subset(TornadoContUS,STATE=="CO")

coordinates(ColTornado)<-c("SLON","SLAT")

class(ColTornado) #"SpatialPointsDataFrame“

Page 8: R Spatial Analysis using SP

str(ColTornado)Formal class 'SpatialPointsDataFrame' [package "sp"] with

5 slots

..@ data :'data.frame': 1762 obs. of 25 variables:

..@ coords.nrs : int [1:2] 16 15 ;data columns

..@ coords : num [1:1762, 1:2] -103 -102 -102 -102 -104 ... ;coordinates longitude, lattitude

.. ..- attr(*, "dimnames")=List of 2 ;column names

..@ bbox : num [1:2, 1:2] -109 37 -102 41

.. ..- attr(*, "dimnames")=List of 2

..@ proj4string:Formal class 'CRS' [package "sp"] with 1 slots ;projection string (we will assign one later)

Page 9: R Spatial Analysis using SP

Spatial Lines and Polygons• Line object is a collection of 2D coordinates (contours).

• Polygon object: Line object with equal first and last coordinates.

• Lines object: list of Line objects (10,000 foot contour lines)

• Polygons object: list of Polygon objects (country with islands)

• SpatialLines or SpatialPolygons objects are made from lists of Lines or Polygons objects (respectively).

• SpatialLinesDataFrame and SpatialPolygonsDataFrame objects – Extends SpatialLines and SpatialPolygons classes,– Contain objects and standard data frames,– require ID field values to match data frame row names.

Page 10: R Spatial Analysis using SP

• Multiple page dotted object denotes list of objects• Bold arrow shows a slot containing a list of objects• Plain arrow shows a slot containing a single object

Spatial Polygons Classes and Slots Diagram

Page 11: R Spatial Analysis using SP

Plotting Spatial Objects Example

Procedure:

1. Create a FACTOR of F values (for plotting).

2. Load Colorado counties map.

3. Convert map to SpatialLines object.

4. Create grid lines and grid text.

5. Us spplot to create plot (and print to display).

Plot Colorado touchdown points colored by Fujita scale on top of a map of Colorado counties with a labeled grid of latitude and longitude lines.

Page 12: R Spatial Analysis using SP

range(ColTornado$FSCALE) #0:3

ColTornado$FSCALE_FACTOR<-ordered(ColTornado$FSCALE,levels=0:5, labels=paste("F",0:5,sep=""))

require(maps) #Load in maps package:

ColMap<-map("county","Colorado",plot=F)

baseCRS<-CRS("+proj=longlat +ellps=WGS84")

#Convert it to a SpatialLines object. You can convert to SpatialPolygons as well. Projection added

ColMapSpLines<- map2SpatialLines(ColMap,proj4string=baseCRS)

ColMapSpLinesLayout<- list("sp.lines",ColMapSpLines,lwd=.6,col="grey50")

Page 13: R Spatial Analysis using SP

#Create grid lines and grid text along with plot layouts

latlonlines<-gridlines(ColMapSpLines,easts= -110:-101 )

latlonlinesLayout<-list("sp.lines",latlonlines,lty=2,col="pink")

latlontext<-gridat(latlonlines)

#Split for better use of positioning

latlontextE<-latlontext[latlontext$pos==1,]

latlontextN<-latlontext[latlontext$pos==2,]

latlontextLayoutE<-list("sp.text",coordinates(latlontextE), parse(text=as.character(latlontextE$labels)),offset=latlontextE$offset[1]/2,pos=1,col="brown")

latlontextLayoutN<-list("sp.text",coordinates(latlontextN), parse(text=as.character(latlontextN$labels)),offset=latlontextN$offset[1]/2,pos=2,col="green")

Page 14: R Spatial Analysis using SP

spLayout<-list(ColMapSpLinesLayout, latlonlinesLayout, latlontextLayoutE, latlontextLayoutN)

spplot(ColTornado["FSCALE_FACTOR"],

pch=20, alpha=.8, key.space="right”,

xlim=c(-109.8,101.5), ylim=c(36.5,41.5), col.regions=c("grey","yellow","orange","red","brown", "black"), main="Colorado Tornadoes from 1950 to 2009", sp.layout=spLayout)

The spplot function

1. plots one color for each FSCAL_FACTOR level.

2. uses trellis graphics from lattice package.

3. adds layers in sp.layout in order.

4. uses alpha for transparency. (density plot)

Page 15: R Spatial Analysis using SP
Page 16: R Spatial Analysis using SP
Page 17: R Spatial Analysis using SP

Counting Storms ExampleThe goal of this example is to count storms in

hexagons of uniform area covering the United States from 1980-2009.

The example demonstrates how to:

1.Convert spatial objects from one CRS to another.

2.Generate a hexagonal lattice as a Spatial Polygon.

3.Use of overlay() to count touchdown points within each polygon.

4.Use spplot() to plot the analysis.

Page 18: R Spatial Analysis using SP

Counting Storms Procedure1. Select 1980-2009 subset of tornado touchdowns.

2. Create a Lambert CRS and project “SLAT”,”SLON” coordinates onto new CRS.

3. Create SpatialPointsDataFrame of touchdowns.

4. Create equal area SpatialPolygons hexagon tiling.

5. Overlay spatial points onto hexagon tiling.1. Use overlay() to return an integer vector identifying the

location of the polygon containing each point.

6. Count touchdown points within each hexagon.

7. Import US map and convert to Lambert CRS.

8. Create gridlines and project onto Lambert CRS.

9. Plot counts on US map with gridlines using spplot.

Page 19: R Spatial Analysis using SP

require(rgdal) #rgdal code in green

projInfo()[55,] #lcc Lambert Conformal Conic

lambertCRS<-

" +proj=lcc +lat_1=60 +lat_2=30 +lon_0=-100"

#Spacing (and lack of) intentional in CRS string.

#project() uses matrix with longitude latitude cols.

#CRS string cannot contain reference ellipsoid.

res=project(cbind(Tornado2$SLON,Tornado2$SLAT), lambertCRS)

Tornado2$x=res[,1]; Tornado2$y=res[,2]

#Make copy, convert to SpatialPointsDataFrame

US_sp=Tornado2

coordinates(US_sp)=~x+y

Page 20: R Spatial Analysis using SP

#Create polygon

coords1<-matrix(c(-125,20, -125,50, -66,50 ,-66,20,-125,20),

ncol=2, byrow=TRUE)

coords=project(coords1,lambertCRS)

pg=Polygon(coords) #rectangle in Lambert CRS

#Sample hexagonal points, convert to polygons

HexPts=spsample(pg, type="hexagonal", n=2750, offset=c(0,0))

HexPols = HexPoints2SpatialPolygons(HexPts)

proj4string(HexPols)<-lambertCRS #" +proj=lcc +lat_1=60 +lat_2=30 +lon_0=-100 +ellps=WGS84“

#transform back into lon, lat coordinates and plot

HexPolsLatLon<-spTransform(HexPols,baseCRS)

Page 21: R Spatial Analysis using SP

plot(HexPolsLatLon,axes=T) #hexagon tiling

Page 22: R Spatial Analysis using SP

#overlay locations, returns hexagon locationlocations=overlay(US_sp,HexPols)#Use of table function to count points in hexagoncounttable<-as.data.frame(

table(factor(locations, levels=1:length(HexPols@polygons))),

row.names=

sapply(HexPols@polygons, function(x) x@ID)

)[,"Freq",drop=F]

colnames(counttable)<-"counts“

HexPolsDf = SpatialPolygonsDataFrame( HexPols, counttable, match.ID = TRUE)

Page 23: R Spatial Analysis using SP

#Create state and gridline map elements

CRSlambert<-CRS(lambertCRS)

usa_lines=map("state",plot=F)

usa_lines_sp=map2SpatialLines( usa_lines,proj4string=baseCRS) #in maptools

usa_lines_sp_trans=spTransform( usa_lines_sp, CRSlambert)

#Create SpatialPolygons object and create grid

frame<-SpatialPolygons(

list(Polygons(list(Polygon(coords1)), "ID1")),

proj4string=baseCRS)t1<-gridlines(frame, norths=seq(25,50,5), easts=seq(-120,-60,15))

grid_lines<-spTransform(t1,CRSlambert)

Page 24: R Spatial Analysis using SP

#Create mappings and plot

L1=list("sp.lines",usa_lines_sp_trans,lwd=.6)G1=list("sp.lines",grid_lines,col="grey50")

#spplot produces object, plotted by print()!spplot(HexPolsDf,lty=0,

col.regions=rev(heat.colors(100)), sp.layout=list(l1,G1), colorkey=list(space="bottom"))

Page 25: R Spatial Analysis using SP
Page 26: R Spatial Analysis using SP

Monthly Tornado Counts and Global Climate Covariates

Is there any relationship between climate covariates and monthly tornado counts for a given hexagon.

• Covariates: monthly NAO, SST, SSN, and SOI?• Our initial investigation will divide monthly

tornado counts by the lower and upper terciles (thirds) of the same month for each covariate. – This generates 2*4*12 observations to be plotted two

at a time. 48 plots each with 2 subplots.

• The 48 plots are combined into a movie using QuickTime Pro, and converted to SWF using Fs

Page 27: R Spatial Analysis using SP

Monthly Covariate Procedure• Download covariates and unstack by month and year.

• Generate monthly quantiles (terciles) for the covariates.

• Merge covariates with climate data.

• Create SpatialPointsDataFrame (SPDF) from merged dataset.

• Overlay SPDF onto hexagon SpatialPolygons tiling.

• Add hexagon id as “hex” column to SPDF.

• Split SPDF by Hexagon id and remove empty hexagons from hexagon tiling (i.e. id not in SPDF@data[“hex”])

• For each covariate and each month, table the tornado touchdown points in the given month by the terciles of the given covariate observed in that month.

• Create SpatialPolygonsDataFrame from result.

• Plot each figure as PNG and combine into movie.

Page 28: R Spatial Analysis using SP

#Download Covariates and create Quantiles

#Climate Covariates from 1861-2009

source("data/climateCovariates.R")

# Green colored functions from:

source("funs/tsupport.R")

startend<-1950:2009 #tornado years

covariates<-make.cov.unstacked(climateCovariates, se=startend,cov=c("soi","nao","sst","sun"))

monthlyquantiles<-as.array.list(lapply(

split(covariates[,-(1:2)], covariates$Month),

function(x) out<- apply(x,2,quantile,probs=c(1/4,1/3,1/2,2/3,3/4) )

),name="Month")

Page 29: R Spatial Analysis using SP

TornadoClimate<-merge(TornadoContUS, covariates, by.x=c("YEAR","MONTH"), by.y=c("Year","Month"))

projcords=project( as.matrix(TornadoClimate[c("SLON","SLAT")]), lambertCRS) #As before

TC<-TornadoClimate

TC$x<-projcords[,1];TC$y<-projcords[,2]

coordinates(TC)=~x+y

hexagonNumber<-overlay(TC,HexPols)

TC$Hex<-hexagonNumber

Page 30: R Spatial Analysis using SP

#Split Hexagons (Will order by hex number)

TCsplit<-split(TC@data,TC$Hex)

names(TCsplit)<-sapply(HexPols@polygons, function(x) x@ID)[as.numeric(names(TCsplit))]

#Remove empty tiles from hexagon tiling. (V10.1 R)

HexPolsMissing<-HexPols[names(TCsplit),]

#Create Yearly Frequency

yearspersplit<-count.storms(x=covariates,cut=3,col.name="Month", quantiles = monthlyquantiles,Year%in%startend)

splitcounts<-data.frame(t(sapply(TCsplit, function(x) count.storms(x,cut=3, FSCALE>=1 & YEAR %in% startend, quantiles = monthlyquantiles) ) /yearspersplit) )

#Create SpatialPolygonsDataFrame

splitcountsSPDF<-SpatialPolygonsDataFrame(HexPolsMissing,splitcounts)

Page 31: R Spatial Analysis using SP

#Create Images

dir.create("./monthlyclimatepng")

png(file="./monthlyclimatepng/plot%03d.png", width=1080, height=600, bg="white",res=120)

for(i in 1:48) #4 covariates 12 months

{

#Plot lower and upper thirds in each plot

print(spplot(splitcountsSPDF[,c(3*i-2,3*i)], lty=0, col.regions=rev(heat.colors(100))[1:90], sp.layout=list(l1,G1), as.table=T,

main="Tornado frequency of F1 or higher split by covariate", colorkey=list(space="bottom")))

}

dev.off()

Page 32: R Spatial Analysis using SP
Page 33: R Spatial Analysis using SP

Final Thoughts1. This is an introduction to the “sp” package

as it relates to our initial work using a tornado data set.

2. We did not get to discuss• GridTopology a base class for• SpatialGrid a rectangular array class and• SpatialPixels a sparse array class

3. Source code and presentation available:• spexample.zip and sp.ppt from

https://public.me.com/thjagger• Examples tested on R V10.1 on 32 bit Vista

– Unzip into dir, start R in dir\spexample– source(“tornado.r”,echo=T) #Creates all figures, x11()