Point-Pattern Analysis is the is the examination of the spatial arrangements of points in (usually 2-dimensional) space. While, PPA allows us to examine patterns, it is what the points represent that allows us to better understand the world around us.
PPA is a big topic in spatial statistics. So for time’s sake (We have much to cover yet!), we won’t be covering anything too crazy. We will be learning how to set up a point pattern analysis study with our data, visualize point density, and use a simple function to estimate relationships and randomness.
Kernel density is a non-parametric way to estimate the probability density function of a random variable.
Spatstat is a family of packages for the statistical analysis of spatial point patterns. Load the Spatstat package.
For this analysis, we are going to be analyzing point patterns for various causes of fires in Tonto National Forest located in central Arizona.
In your week 9 data folder, you should find two shapefiles:
fire_tonto.shp (Fire occurrence starting points)
Tonto_NF.shp (Tonto National Forest Boundary)
fire <- terra::vect("D:/R Textbook Template/NR6950 Notebook/NR 6950 Notebook/Data/Point_pattern/fire_tonto.shp")
tonto <- terra::vect("D:/R Textbook Template/NR6950 Notebook/NR 6950 Notebook/Data/Point_pattern/Tonto_NF.shp")
fire <- terra::project(fire, prj.aeaN83)
tonto <- terra::project(tonto, prj.aeaN83)
head(fire,5)
## FIRE_NAME LOCAL_FIRE LOCATION TOWNSHIP RANGE SECTION SUB_SECTIO
## 1 DEER 16 HWY 87 MP 238 0080N 0100E 05 NW
## 2 WEDNESDAY 0070N 0130E 23 NWNE
## 3 MAGGIE 0070N 0050E 6 NW
## 4 BIRCH 0100N 0100E 31 SENW
## 5
## PRINCIPAL_ REPORT_UNI REPORT_U_1 DISTRICT FIRE_NUMBE
## 1 GILA AND SALT RIVER 0312 Tonto National Forest 06 174
## 2 GILA AND SALT RIVER 0312 Tonto National Forest 05 219
## 3 GILA AND SALT RIVER 0312 Tonto National Forest 01 081
## 4 GILA AND SALT RIVER 0312 Tonto National Forest 04 099
## 5 NEW MEXICO 0306 Gila National Forest 03 040
## ADMIN_UNIT ADMIN_UN_1 PROTECTING PROTECTION
## 1 0312 Tonto National Forest USFS - USDA Forest Service
## 2 0312 Tonto National Forest USFS - USDA Forest Service
## 3 0312 Tonto National Forest USFS - USDA Forest Service
## 4 0312 Tonto National Forest USFS - USDA Forest Service
## 5 0306 Gila National Forest USFS - USDA Forest Service
## PROTECTI_1 OWNERSHIP_ OWNERSHIP1 OWNERSHI_1 TOPO_LANDF STATE_CODE
## 1 1 - National Forest 04
## 2 1 - National Forest 04
## 3 1 - National Forest 04
## 4 1 - National Forest 04
## 5 1 - National Forest 35
## STATE_NAME COUNTY COUNTY_NAM COUNTY_STA FIRE_MANAG POO_LATITU POO_LONGIT
## 1 AZ - ARIZONA 007 Gila 04 P3BEY6 34.07250 -111.3578
## 2 AZ - ARIZONA 007 Gila P38601 33.95222 -110.9842
## 3 AZ - ARIZONA 013 Maricopa P38601 33.96861 -111.8833
## 4 AZ - ARIZONA 007 Gila P38601 34.25139 -111.3678
## 5 NM - NEW MEXICO 35 34.01667 -111.8333
## LAT_DEG LAT_MIN LAT_SEC LONG_DEG LONG_MIN LONG_SEC DISCOVER_Y IGNITION
## 1 34 4 21 111 21 28 2005 2005/08/14
## 2 33 57 8 110 59 3 1999 1999/07/18
## 3 33 58 7 111 53 0 1999 1999/05/24
## 4 34 15 5 111 22 4 1999 1999/06/04
## 5 34 1 0 111 50 0 1991 1991/06/05
## DISCOVERY INITIAL_RE FIRE_DETEC DISCOVERED
## 1 2005/08/14 2005/08/14 45 - Cooperator or Coop employ DPS
## 2 1999/07/21 1999/07/21 1 - Agency Lookout
## 3 1999/05/24 1999/05/24 0 - Others
## 4 1999/06/04 1999/06/04 0 - Others
## 5 1991/06/06 1991/06/06 1 - Agency Lookout
## STATISTICA INITIAL_ST STRATEGY_M OBJECTIVES COMPLEX_FI
## 1 9 - Miscellaneous Suppression 2005/08/14
## 2 1 - Lightning Suppression 1999/07/21
## 3 9 - Miscellaneous Suppression 1999/05/24
## 4 4 - Campfire Suppression 1999/06/04
## 5 1 - Lightning 3 - Control (1983-1998) 1991/06/06
## COMPLEX_NA CONTAINED FIRE_OUT AGENCY_ACR OTHER_ACRE OTHER_AC_1 TOTAL_ACRE
## 1 2005/08/14 0.1 0 0 0.1
## 2 1999/07/30 2.0 0 0 2.0
## 3 1999/05/24 0.1 0 0 0.1
## 4 1999/06/04 0.1 0 0 0.1
## 5 1991/06/10 2.5 0 0 2.5
## FIRE_SIZE_ PRESCRIBED PRESCRIB_1 WUI_FIRE WUI_ACRES
## 1 A - .00-.25 Acres N 0 0
## 2 B - .26-9.99 Acres N 0 0
## 3 A - .00-.25 Acres N 0 0
## 4 A - .00-.25 Acres N 0 0
## 5 B - .26-9.99 Acres N 0 0
## FIRE_INTEN REP_WX_STA STATION_TY STATION_NA WIND_SPEED
## 1 1 - Flame Length 0-2' 20604 0 0
## 2 1 - Flame Length 0-2' 20603 4 PLEASANT VALLEY 0
## 3 4 - Flame Length >6-8' 20604 0 0
## 4 1 - Flame Length 0-2' 20603 4 PLEASANT VALLEY 0
## 5 2 - Flame Length >2-4' 292005 4 RESERVE 0
## NFDRS_FUEL OTHER_FUEL COVER_CLAS
## 1 L - Western Perennial Grasses 0 11 - Grass-Low resist ctrl
## 2 R - Hrdwd. Litter (Summer) 0 41 - Mixed conifer-Low resist ctrl
## 3 B - Mature Brush (Chaparral) 0 52 - Brush-Med resist ctrl
## 4 T - Sagebrush w/ Grass 0 11 - Grass-Low resist ctrl
## 5 K - Light Slash 0 -
## SLOPE ASPECT ELEVATION LOCAL_TIME RECORD_ENT SUBMITTED_ APPROVED_D
## 1 0 0 Flat 2500 America/Phoenix 2005/09/02 2005/09/02 2005/09/02
## 2 0 7 West 6000 America/Phoenix 2000/04/25
## 3 5 6 Southwest 3600 America/Phoenix 2000/04/19
## 4 2 0 Flat 5200 America/Phoenix 2000/04/19
## 5 5 9 Ridgetop 8500 America/Phoenix 1992/02/26
## CREATED_DA LAST_MODIF
## 1 2005/09/02 2015/12/09
## 2 2005/02/04 2015/12/09
## 3 2005/02/04 2015/12/09
## 4 2005/02/04 2015/12/09
## 5 2005/02/04 2015/12/09
The fire points shapefile contains a column called “STATISTICA”, which contains the different classes of fire starts.
Let’s go ahead and give our data some initial plotting.
terra::plot(fire, "STATISTICA", plg=list(x="bottomleft", title = "Ignition Cause"),
pax=list(las=1), main = "Fire Starts")
terra::plot(tonto, add = T)
as.owin() is the function for creating an “observation window” for point pattern analysis. Basically it creates the bounding box for which inside our analysis will take place.
terra::plot(tonto)
In our case, we want to look at point pattern analysis within Tonto National Forest. We will turn that polygon into our “owin”.
library(spatstat)
tontoOwin <- as.owin(sf::st_as_sf(tonto))
class(tontoOwin)
## [1] "owin"
NOTE: We brought in our shapefiles as spatvectors through the terra library. We must have our shapefile be an sf object to become an “owin”. Use st_as_sf() to change our spatvector to sf.
The function ppp() works on changing the coordinates of a dataset of points (our fire starts) into the class “ppp”. “ppp” represents a point pattern dataset in the two-dimensional plane.
To create a “ppp” you must create a dataset that has only coordinates. We can do this by using crds() from the terra package.
pts <- terra::crds(fire)
head(pts)
## x y
## [1,] -1400789 1336513
## [2,] -1369109 1317797
## [3,] -1450217 1332942
## [4,] -1398473 1356396
## [5,] -1444803 1337477
## [6,] -1427220 1287664
Now that we have our coordinates, we can develop our ppp by using the function and following syntax:
variable <- ppp(point_dataset[,1], point_dataset[,2], window = tontoOwin)
[,1] & [,2] refer to each column within our dataset (longitude and latitude) and the window refers to the observation window we created of the Tonto National Forest polygon.
p <- ppp(pts[,1], pts[,2], window=tontoOwin) # define x and y point and window
## Warning: data contain duplicated points
p # what does this look like?
## Planar point pattern: 8307 points
## window: polygonal boundary
## enclosing rectangle: [-1467940.3, -1330040.8] x [1234332.1, 1379166.6] units
plot(p) # plots the ppp (points) and the window (boundary) together.
density(), from the stats package (don’t worry, it’s already loaded for you in R by default), computed the kernel density estimates from a point pattern dataset (our “ppp”). Simply put in our “ppp” which is assigned to p.
ds <- density(p)
If we check the class of “ds” we will see it is “im”.
class(ds)
## [1] "im"
“im” represents a two-dimensional pixel image.
–
And as simple as that, we can plot the kernel density estimates for our point pattern of fire starts!
plot(ds, main='fire start density')
Below is some code for a for-loop that sets up a quick plot of 4 specific fire start causes. We will generate point density and test whether two of these have spatial relationships.
For this example, We will examine fires caused by:
Equipment Use
Smoking
Campfires
Arson
par(mfrow=c(2,2))
for (type in c("2 - Equipment Use", "3 - Smoking", "4 - Campfire", "7 - Arson")) {
plot(tonto, col='grey')
fire_t <- fire[fire$STATISTICA == type, ]
points(fire_t, col = "red")
title(type)
}
We can do the same process as above for all of the objects in the dataset at once by using marks = withon our ppp() function.
The categories for fire starts are within the fire point dataset under the column STATISTICA. Since these categories are text and not factors, the ppp() function wont understand that they are really different categories of fire starts.
We can produce a ppp class that has each category readily available to plot as a density.
In our code below, lets make the fire categories a factor and then assign them to our marks =.
# add in marks by using as.factor() around the column of interest.
mpp <- ppp(pts[,1], pts[,2], window = tontoOwin, marks=as.factor(fire$STATISTICA))
## Warning: data contain duplicated points
Now lets plot the 4 point patterns of interest.
spp <- split(mpp) # divides data into groups based upon marks = above
plot(density(spp[c(2:4, 7)]), main='') # Plot Densities
Now that we have generated point patterns for our fire starts, we can do a quick test to see if they is any clustering of two sets of patterns or to infer there is any relationship to their occurrences.
Using the envelope() function, we will examine clustering between smoking are arson point patterns. The syntax is as follows:
**variable <- envelope(ppp variable, Kcross, nsim = # of choice, i = “variable 1”, j = “variable 2”)
NOTE:
Let’s plot:
ekc <- envelope(mpp, Kcross, nsim = 5, i = "3 - Smoking", j = "7 - Arson")
## Generating 5 simulations of CSR ...
## 1, 2, [etd 3:22] 3, [etd 2:56] 4,
## [etd 1:25] 5.
##
## Done.
plot(ekc, main = "Smoking and Arson")
The dashed red line in our KCross plot represents the reference line for complete spatial randomness between the two point patterns.
The grey line around the red line is the randomization envelope.
The black line represent the Kcross function for these two point patterns.
So our black line is quite a bit higher than the red dashed line. This gives us evidence that there is clustering of the two point patterns in this example.