R Spatial Analysis using SP

20,841 views

Published on

This is an introduction to the R SP package.

0 Comments
10 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
20,841
On SlideShare
0
From Embeds
0
Number of Embeds
512
Actions
Shares
0
Downloads
417
Comments
0
Likes
10
Embeds 0
No embeds

No notes for slide
  • We discuss Climate signals in damage losses for North Atlantic Hurricanes along the Gulf and East coast of the US. (This excludes Hawaii in this model).
  • R Spatial Analysis using SP

    1. 1. Applied Spatial Data Analysis using R Thomas Jagger Department of Geography Florida State University Denver R User Group Meeting October 19, 2010 TexPoint fonts used in EMF. Read the TexPoint manual before you delete this box.: A A A A with special thanks to Roger Bivand: http://www.asdar-book.org
    2. 2. Topics <ul><ul><li>Spatial objects in the “sp” Package </li></ul></ul><ul><ul><ul><li>Points, Lines, Polygons, Pixels and Grids </li></ul></ul></ul><ul><ul><li>The S4 Framework </li></ul></ul><ul><ul><ul><li>Classes, slots, methods, inheritance </li></ul></ul></ul><ul><ul><li>How to create, convert, explore and manipulate “sp” spatial objects. </li></ul></ul><ul><ul><li>Example: Analyzing tornado data using the R “sp” package. </li></ul></ul>
    3. 3. Sources of Information <ul><li>Spatial data: </li></ul><ul><li>http://cran.r-project.org/web/views/Spatial.html </li></ul><ul><li>http://r-spatial.sourceforge.net/ </li></ul><ul><li>vignette(&quot;sp&quot;) </li></ul><ul><li>Rnews: http://cran.r-project.org/doc/Rnews/Rnews_2005-2.pdf </li></ul><ul><li>Applied Spatial Data Analysis with R </li></ul><ul><li>http://spatial-analyst.net wiki </li></ul><ul><li>Plotting </li></ul><ul><li>http://r-spatial.sourceforge.net/gallery/ </li></ul><ul><li>Figures for ASDAR </li></ul><ul><li>Tornado data from the Storm Prediction Center (SPC) </li></ul><ul><li>Slides on Spatial Data Courtesy of Roger Bivand </li></ul><ul><li>http://spatial-analyst.net/Rosgeo/sites/default/files/plasencia_monday_R.pdf </li></ul>
    4. 4. Object Framework <ul><li>To begin with, all contributed packages for handling spatial data in R had different representations of the data. </li></ul><ul><li>This made it difficult to exchange data both within R between packages, and between R and external file formats and applications. </li></ul><ul><li>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. </li></ul><ul><li>Roger Bivand and his collaborators chose to use new-style classes to represent spatial data and they are confident that this choice was justified. </li></ul>
    5. 5. Spatial Points <ul><li>The most basic spatial data object is a point, which may have 2 or 3 dimensions </li></ul><ul><li>Consists of a single coordinate, or a set of such coordinates. </li></ul><ul><li>To define a SpatialPoints object; coordinates should be of mode double and will be promoted if not already. </li></ul><ul><li>The points in a SpatialPoints object may be associated with a row of attributes to create a SpatialPointsDataFrame object </li></ul><ul><li>The coordinates and attributes may, but do not have to be keyed to each other using ID value. </li></ul><ul><li>Objects can be manipulated as a data frame though they appear as GIS objects i.e. features with attributes. </li></ul><ul><li>Spatial objects rarely created from scratch, rather they are created by promoting another object such as a data frame into a SpatialPointsDataFrame object. </li></ul>
    6. 6. Spatial Points Diagram <ul><li>The boxes are the object classes definition </li></ul><ul><ul><li>Blue is the class name </li></ul></ul><ul><ul><li>White represents slots within each class </li></ul></ul><ul><ul><li>Arrows show inheritance </li></ul></ul>
    7. 7. Spatial Points Example: Colorado Tornado Touchdowns <ul><li>require(sp) </li></ul><ul><li>download.file(&quot;http://www.spc.noaa.gov/gis/svrgis/Tornado_touchdown_points.zip&quot;,&quot;Tornado_touchdown_points.zip&quot;,mode=&quot;wb&quot;) </li></ul><ul><li>require(maptools) </li></ul><ul><li>Tornado<-read.dbf(zip.file.extract(&quot;Tornado_touchdown_points.dbf&quot;,zip=&quot;Tornado_touchdown_points.zip&quot;)) </li></ul><ul><li>TornadoContUS<-subset(Tornado, !(FIPS %in% c(2,66,15,60,72,78,99)) & SLAT !=0 & SG ==1 & FSCALE >=0) </li></ul><ul><li>ColTornado<-subset(TornadoContUS,STATE==&quot;CO&quot;) </li></ul><ul><li>coordinates(ColTornado)<-c(&quot;SLON&quot;,&quot;SLAT&quot;) </li></ul><ul><li>class(ColTornado) #&quot;SpatialPointsDataFrame“ </li></ul>
    8. 8. <ul><li>str(ColTornado) </li></ul><ul><li>Formal class 'SpatialPointsDataFrame' [package &quot;sp&quot;] with 5 slots </li></ul><ul><li>..@ data :'data.frame': 1762 obs. of 25 variables: </li></ul><ul><li>..@ coords.nrs : int [1:2] 16 15 ; data columns </li></ul><ul><li>..@ coords : num [1:1762, 1:2] -103 -102 -102 -102 -104 ... ;coordinates longitude, lattitude </li></ul><ul><li>.. ..- attr(*, &quot;dimnames&quot;)=List of 2 ;column names </li></ul><ul><li>..@ bbox : num [1:2, 1:2] -109 37 -102 41 </li></ul><ul><li>.. ..- attr(*, &quot;dimnames&quot;)=List of 2 </li></ul><ul><li>..@ proj4string:Formal class 'CRS' [package &quot;sp&quot;] with 1 slots ;projection string (we will assign one later) </li></ul>
    9. 9. Spatial Lines and Polygons <ul><li>Line object is a collection of 2D coordinates (contours). </li></ul><ul><li>Polygon object: Line object with equal first and last coordinates. </li></ul><ul><li>Lines object: list of Line objects (10,000 foot contour lines) </li></ul><ul><li>Polygons object: list of Polygon objects (country with islands) </li></ul><ul><li>SpatialLines or SpatialPolygons objects are made from lists of Lines or Polygons objects (respectively). </li></ul><ul><li>SpatialLinesDataFrame and SpatialPolygonsDataFrame objects </li></ul><ul><ul><li>Extends SpatialLines and SpatialPolygons classes, </li></ul></ul><ul><ul><li>Contain objects and standard data frames, </li></ul></ul><ul><ul><li>require ID field values to match data frame row names. </li></ul></ul>
    10. 10. <ul><li>Multiple page dotted object denotes list of objects </li></ul><ul><li>Bold arrow shows a slot containing a list of objects </li></ul><ul><li>Plain arrow shows a slot containing a single object </li></ul>Spatial Polygons Classes and Slots Diagram
    11. 11. Plotting Spatial Objects Example <ul><li>Procedure: </li></ul><ul><li>Create a FACTOR of F values (for plotting). </li></ul><ul><li>Load Colorado counties map. </li></ul><ul><li>Convert map to SpatialLines object. </li></ul><ul><li>Create grid lines and grid text. </li></ul><ul><li>Us spplot to create plot (and print to display). </li></ul><ul><ul><li>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. </li></ul></ul>
    12. 12. <ul><li>range(ColTornado$FSCALE) #0:3 </li></ul><ul><li>ColTornado$FSCALE_FACTOR<-ordered(ColTornado$FSCALE,levels=0:5, labels=paste(&quot;F&quot;,0:5,sep=&quot;&quot;)) </li></ul><ul><li>require(maps) #Load in maps package: </li></ul><ul><li>ColMap<-map(&quot;county&quot;,&quot;Colorado&quot;,plot=F) </li></ul><ul><li>baseCRS<-CRS(&quot;+proj=longlat +ellps=WGS84&quot;) </li></ul><ul><li>#Convert it to a SpatialLines object. You can convert to SpatialPolygons as well. Projection added </li></ul><ul><li>ColMapSpLines<- map2SpatialLines(ColMap,proj4string=baseCRS) </li></ul><ul><li>ColMapSpLinesLayout<- list(&quot;sp.lines&quot;,ColMapSpLines,lwd=.6,col=&quot;grey50&quot;) </li></ul>
    13. 13. <ul><li>#Create grid lines and grid text along with plot layouts </li></ul><ul><li>latlonlines<-gridlines(ColMapSpLines,easts= -110:-101 ) </li></ul><ul><li>latlonlinesLayout<-list(&quot;sp.lines&quot;,latlonlines,lty=2,col=&quot;pink&quot;) </li></ul><ul><li>latlontext<-gridat(latlonlines) </li></ul><ul><li>#Split for better use of positioning </li></ul><ul><li>latlontextE<-latlontext[latlontext$pos==1,] </li></ul><ul><li>latlontextN<-latlontext[latlontext$pos==2,] </li></ul><ul><li>latlontextLayoutE<-list(&quot;sp.text&quot;,coordinates(latlontextE), parse(text=as.character(latlontextE$labels)),offset=latlontextE$offset[1]/2,pos=1,col=&quot;brown&quot;) </li></ul><ul><li>latlontextLayoutN<-list(&quot;sp.text&quot;,coordinates(latlontextN), parse(text=as.character(latlontextN$labels)),offset=latlontextN$offset[1]/2,pos=2,col=&quot;green&quot;) </li></ul>
    14. 14. <ul><li>spLayout<-list(ColMapSpLinesLayout, latlonlinesLayout, latlontextLayoutE, latlontextLayoutN) </li></ul><ul><li>spplot(ColTornado[&quot;FSCALE_FACTOR&quot;], </li></ul><ul><li>pch=20, alpha=.8, key.space=&quot;right”, </li></ul><ul><li>xlim=c(-109.8,101.5), ylim=c(36.5,41.5), col.regions= c(&quot;grey&quot;,&quot;yellow&quot;,&quot;orange&quot;,&quot;red&quot;,&quot;brown&quot;, &quot;black&quot;), main=&quot;Colorado Tornadoes from 1950 to 2009&quot;, sp.layout=spLayout) </li></ul><ul><li>The spplot function </li></ul><ul><li>plots one color for each FSCAL_FACTOR level. </li></ul><ul><li>uses trellis graphics from lattice package. </li></ul><ul><li>adds layers in sp.layout in order. </li></ul><ul><li>uses alpha for transparency. (density plot) </li></ul>
    15. 17. Counting Storms Example <ul><li>The goal of this example is to count storms in hexagons of uniform area covering the United States from 1980-2009. </li></ul><ul><li>The example demonstrates how to: </li></ul><ul><li>Convert spatial objects from one CRS to another. </li></ul><ul><li>Generate a hexagonal lattice as a Spatial Polygon. </li></ul><ul><li>Use of overlay() to count touchdown points within each polygon. </li></ul><ul><li>Use spplot() to plot the analysis. </li></ul>
    16. 18. Counting Storms Procedure <ul><li>Select 1980-2009 subset of tornado touchdowns. </li></ul><ul><li>Create a Lambert CRS and project “SLAT”,”SLON” coordinates onto new CRS. </li></ul><ul><li>Create SpatialPointsDataFrame of touchdowns. </li></ul><ul><li>Create equal area SpatialPolygons hexagon tiling. </li></ul><ul><li>Overlay spatial points onto hexagon tiling. </li></ul><ul><ul><li>Use overlay() to return an integer vector identifying the location of the polygon containing each point. </li></ul></ul><ul><li>Count touchdown points within each hexagon. </li></ul><ul><li>Import US map and convert to Lambert CRS. </li></ul><ul><li>Create gridlines and project onto Lambert CRS. </li></ul><ul><li>Plot counts on US map with gridlines using spplot . </li></ul>
    17. 19. <ul><li>require(rgdal) #rgdal code in green </li></ul><ul><li>projInfo()[55,] # lcc Lambert Conformal Conic </li></ul><ul><li>lambertCRS<- </li></ul><ul><li>&quot; +proj=lcc +lat_1=60 +lat_2=30 +lon_0=-100&quot; </li></ul><ul><li>#Spacing (and lack of) intentional in CRS string. </li></ul><ul><li>#project() uses matrix with longitude latitude cols. </li></ul><ul><li>#CRS string cannot contain reference ellipsoid. </li></ul><ul><li>res=project( cbind(Tornado2$SLON,Tornado2$SLAT ), lambertCRS) </li></ul><ul><li>Tornado2$x=res[,1]; Tornado2$y=res[,2] </li></ul><ul><li>#Make copy, convert to SpatialPointsDataFrame </li></ul><ul><li>US_sp=Tornado2 </li></ul><ul><li>coordinates(US_sp)=~x+y </li></ul>
    18. 20. <ul><li>#Create polygon </li></ul><ul><li>coords1<-matrix( c(-125,20, -125,50, -66,50 ,-66,20,-125,20), </li></ul><ul><li>ncol=2, byrow=TRUE) </li></ul><ul><li>coords=project(coords1,lambertCRS) </li></ul><ul><li>pg=Polygon(coords) #rectangle in Lambert CRS </li></ul><ul><li>#Sample hexagonal points, convert to polygons </li></ul><ul><li>HexPts=spsample(pg, type=&quot;hexagonal&quot;, n=2750, offset=c(0,0)) </li></ul><ul><li>HexPols = HexPoints2SpatialPolygons(HexPts) </li></ul><ul><li>proj4string(HexPols)<-lambertCRS </li></ul><ul><li>#&quot; +proj=lcc +lat_1=60 +lat_2=30 +lon_0=-100 +ellps=WGS84 “ </li></ul><ul><li>#transform back into lon, lat coordinates and plot </li></ul><ul><li>HexPolsLatLon<-spTransform(HexPols,baseCRS) </li></ul>
    19. 21. plot(HexPolsLatLon,axes=T) #hexagon tiling
    20. 22. <ul><li>#overlay locations, returns hexagon location </li></ul><ul><li>locations=overlay(US_sp,HexPols) </li></ul><ul><li>#Use of table function to count points in hexagon </li></ul><ul><li>counttable<-as.data.frame ( </li></ul><ul><li>table( factor(locations, levels=1: length(HexPols@polygons) ) ) , </li></ul><ul><li>row.names= </li></ul><ul><li>sapply(HexPols@polygons, function(x) [email_address] ) </li></ul><ul><li>) [,&quot;Freq&quot;,drop=F] </li></ul><ul><li>colnames(counttable)<-&quot;counts“ </li></ul><ul><li>HexPolsDf = SpatialPolygonsDataFrame( HexPols, counttable, match.ID = TRUE) </li></ul>
    21. 23. <ul><li>#Create state and gridline map elements </li></ul><ul><li>CRSlambert<-CRS(lambertCRS) </li></ul><ul><li>usa_lines=map(&quot;state&quot;,plot=F) </li></ul><ul><li>usa_lines_sp=map2SpatialLines( usa_lines,proj4string=baseCRS) #in maptools </li></ul><ul><li>usa_lines_sp_trans=spTransform( usa_lines_sp, CRSlambert) </li></ul><ul><li>#Create SpatialPolygons object and create grid </li></ul><ul><li>frame<-SpatialPolygons( </li></ul><ul><li>list( Polygons( list( Polygon( coords1 ) ), &quot;ID1&quot;) ), </li></ul><ul><li>proj4string=baseCRS) </li></ul><ul><li>t1<-gridlines(frame , norths =seq(25,50,5), easts =seq(-120,-60,15)) </li></ul><ul><li>grid_lines<-spTransform(t1,CRSlambert) </li></ul>
    22. 24. <ul><li>#Create mappings and plot </li></ul><ul><li>L1=list(&quot;sp.lines&quot;,usa_lines_sp_trans,lwd=.6) </li></ul><ul><li>G1=list(&quot;sp.lines&quot;,grid_lines,col=&quot;grey50&quot;) </li></ul><ul><li>#spplot produces object, plotted by print()! </li></ul><ul><li>spplot(HexPolsDf,lty=0, col.regions=rev(heat.colors(100)), sp.layout=list(l1,G1), colorkey=list(space=&quot;bottom&quot;)) </li></ul>
    23. 26. Monthly Tornado Counts and Global Climate Covariates <ul><li>Is there any relationship between climate covariates and monthly tornado counts for a given hexagon. </li></ul><ul><li>Covariates: monthly NAO, SST, SSN, and SOI? </li></ul><ul><li>Our initial investigation will divide monthly tornado counts by the lower and upper terciles (thirds) of the same month for each covariate. </li></ul><ul><ul><li>This generates 2*4*12 observations to be plotted two at a time. 48 plots each with 2 subplots. </li></ul></ul><ul><li>The 48 plots are combined into a movie using QuickTime Pro, and converted to SWF using Fs </li></ul>
    24. 27. Monthly Covariate Procedure <ul><li>Download covariates and unstack by month and year. </li></ul><ul><li>Generate monthly quantiles (terciles) for the covariates. </li></ul><ul><li>Merge covariates with climate data. </li></ul><ul><li>Create SpatialPointsDataFrame (SPDF) from merged dataset. </li></ul><ul><li>Overlay SPDF onto hexagon SpatialPolygons tiling. </li></ul><ul><li>Add hexagon id as “hex” column to SPDF. </li></ul><ul><li>Split SPDF by Hexagon id and remove empty hexagons from hexagon tiling (i.e. id not in SPDF@data[“hex”]) </li></ul><ul><li>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. </li></ul><ul><li>Create SpatialPolygonsDataFrame from result. </li></ul><ul><li>Plot each figure as PNG and combine into movie. </li></ul>
    25. 28. <ul><li>#Download Covariates and create Quantiles </li></ul><ul><li>#Climate Covariates from 1861-2009 </li></ul><ul><li>source(&quot;data/climateCovariates.R&quot;) </li></ul><ul><li># Green colored functions from: </li></ul><ul><li>source(&quot;funs/tsupport.R&quot;) </li></ul><ul><li>startend<-1950:2009 #tornado years </li></ul><ul><li>covariates<- make.cov.unstacked (climateCovariates, se=startend,cov=c(&quot;soi&quot;,&quot;nao&quot;,&quot;sst&quot;,&quot;sun&quot;)) </li></ul><ul><li>monthlyquantiles<- as.array.list ( lapply( </li></ul><ul><li>split(covariates[,-(1:2)], covariates$Month), </li></ul><ul><li>function(x) out<- apply(x,2,quantile,probs=c(1/4,1/3,1/2,2/3,3/4) ) </li></ul><ul><li>) , name=&quot;Month&quot; ) </li></ul>
    26. 29. <ul><li>TornadoClimate<-merge(TornadoContUS, covariates, by.x=c(&quot;YEAR&quot;,&quot;MONTH&quot;), by.y=c(&quot;Year&quot;,&quot;Month&quot;)) </li></ul><ul><li>projcords=project( as.matrix(TornadoClimate[c(&quot;SLON&quot;,&quot;SLAT&quot;)]), lambertCRS) #As before </li></ul><ul><li>TC<-TornadoClimate </li></ul><ul><li>TC$x<-projcords[,1];TC$y<-projcords[,2] </li></ul><ul><li>coordinates(TC)=~x+y </li></ul><ul><li>hexagonNumber<-overlay(TC,HexPols) </li></ul><ul><li>TC$Hex<-hexagonNumber </li></ul>
    27. 30. <ul><li>#Split Hexagons (Will order by hex number) </li></ul><ul><li>TCsplit <-split(TC@data,TC$Hex) </li></ul><ul><li>names( TCsplit )<-sapply(HexPols@polygons, function(x) x@ID)[as.numeric(names( TCsplit ))] </li></ul><ul><li>#Remove empty tiles from hexagon tiling. (V10.1 R) </li></ul><ul><li>HexPolsMissing<-HexPols[names(TCsplit),] </li></ul><ul><li>#Create Yearly Frequency </li></ul><ul><li>yearspersplit <- count.storms (x=covariates,cut=3,col.name=&quot;Month&quot;, quantiles = monthlyquantiles,Year%in%startend) </li></ul><ul><li>splitcounts<-data.frame(t(sapply( TCsplit , function(x) count.storms ( x,cut=3, FSCALE>=1 & YEAR %in% startend , quantiles = monthlyquantiles ) ) / yearspersplit ) ) </li></ul><ul><li>#Create SpatialPolygonsDataFrame </li></ul><ul><li>splitcountsSPDF<-SpatialPolygonsDataFrame(HexPolsMissing,splitcounts) </li></ul>
    28. 31. <ul><li>#Create Images </li></ul><ul><li>dir.create(&quot;./monthlyclimatepng&quot;) </li></ul><ul><li>png(file=&quot;./monthlyclimatepng/plot%03d.png&quot;, width=1080, height=600, bg=&quot;white&quot;,res=120) </li></ul><ul><li>for(i in 1:48) #4 covariates 12 months </li></ul><ul><li>{ </li></ul><ul><li>#Plot lower and upper thirds in each plot </li></ul><ul><li>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 , </li></ul><ul><li>main=&quot;Tornado frequency of F1 or higher split by covariate&quot;, colorkey=list(space=&quot;bottom&quot;)) ) </li></ul><ul><li>} </li></ul><ul><li>dev.off() </li></ul>
    29. 33. Final Thoughts <ul><li>This is an introduction to the “sp” package as it relates to our initial work using a tornado data set. </li></ul><ul><li>We did not get to discuss </li></ul><ul><ul><li>GridTopology a base class for </li></ul></ul><ul><ul><li>SpatialGrid a rectangular array class and </li></ul></ul><ul><ul><li>SpatialPixels a sparse array class </li></ul></ul><ul><li>Source code and presentation available: </li></ul><ul><ul><li>spexample.zip and sp.ppt from https://public.me.com/thjagger </li></ul></ul><ul><ul><li>Examples tested on R V10.1 on 32 bit Vista </li></ul></ul><ul><ul><ul><li>Unzip into dir, start R in dirspexample </li></ul></ul></ul><ul><ul><ul><li>source(“tornado.r”,echo=T) #Creates all figures, x11() </li></ul></ul></ul>

    ×