2

I have a question similar to this one from 2014, which was answered but the datasets are no longer available and our original data structures differ. (I'm in crunch time and stumped, so if you're able to respond quickly I would greatly appreciate it!!)

Goal: use the type of bedrock as a covariate in a Point Process Model (ppm) in spatstat with mine locations in Connecticut.

Data: the files are available from this Dropbox folder. The rock data and CT poly outline comes from UConn Magic Library, and the mine data comes from the USGS Mineral Resources Data System.

Approach: I loaded some relevant packages and read in the shapefiles (and converted coords to match CT's system), and used the CT polygon as an owin object.

library(rgdal)
library(splancs)
library(spatstat)
library(sp)
library(raster) 
library(geostatsp)

#read in shapefiles
ct <-readOGR(".","CONNECTICUT_STATE_POLY")
mrds <-readOGR(".","mrds-2017-02-20-23-30-58") 
rock<-readOGR(".","bedrockpolyct_37800_0000_2000_s50_ctgnhs_1_shp_wgs84")

#convert mrds and rock to ct's coord system
tempcrs<-ct@proj4string
mrds<-spTransform(mrds,tempcrs)
rock<-spTransform(rock,tempcrs)

#turn ct shapefile into owin, call it w for window
w <-as.owin(ct)

#subset mrds data to just CT mines
mrdsCT <-subset(mrds,mrds@data$state=="Connecticut")

#ppm can't handle marked data yet, so need to unmark() 

#create ppp object for mrds data, set window to w
mrdsCT.ppp <-as.ppp(mrdsCT)
Window(mrdsCT.ppp)<-w

From "Modelling Spatial Point Patterns in R" by Baddeley & Turner (page 39): Unfortunately a pixel image in spatstat cannot have categorical (factor) values, because R refuses to create a factor-valued matrix. In order to represent a categorical variate as a pixel image, the categorical values should be encoded as integers (for efficiency’s sake) and assigned to an integer-valued pixel image. Then the model formula should invoke the factor command on this image. For example if fim is an image with integer values which represent levels of a factor, then:

ppm(X, ˜factor(f), Poisson(), covariates=list(f=fim))

There are several different types of rock classification included in the shapefile. I'm interested in LITHO1, which is a factor with 27 levels. It's the sixth attribute.

litho1<-rock[,6]

My (limited but researched) understanding is that I need to convert the shapefile to a raster, and later convert it to an image in order to be used in ppm. I created a mask from ct, and used that.

ctmask<-raster(ct, resolution=2000) 
ctmask[!is.na(ctmask)] <- 0
litho1rast<-rasterize(litho1,ctmask) 

After this point, I've tried several approaches and haven't had success just yet. I've attempted to follow the approaches laid out in the question linked, as well as search in documentation for relevant examples to adopt (factor, ratify, levels). Unlike the prior question, my data was already a factor, so it wasn't clear why I should apply the factor function to it.

Looking at litho1rast, the @data@attributes dataframe contains the following. If I plot it, it just plots the ID; levelplot function does plot LITHO1. When I would apply the factor functions, the ID would be retained but not LITHO1.

$ ID    : int [1:1891] 1 2 3 4 5 6 7 8 9 10 ...    
$ LITHO1: Factor w/ 27 levels "amphibolite",..: 23 16 23 16 23 16 24 23 16 24 ... 

The ppm model would need an object class im, so I converted the raster to the im. I tried two ways. I can make ppm execute...but it treats every point as a factor rather than the 27 levels (with either litho1.im or litho1.im2) ...

litho1.im<-as.im(litho1rast)
litho1.im2<-as.im.RasterLayer(litho1rast)

model1=ppm(unmark(mrdsCT.ppp) ~ factor(COV1), covariates=list(COV1=litho1.im))
model1

So, I'm not quite sure where to go from here. It seems like I need to pass an argument to the as.im so that it knows to retain the LITHO1 not the ID. Clever ideas or leads to pertinent functions or approaches much appreciated!

treedm
  • 33
  • 5

2 Answers2

1

Looking at your code you don't seem to be providing the field argument to rasterize.

From rasterize help:

fieldnumeric or character. The value(s) to be transferred. This can be a single number, or a vector of numbers that has the same length as the number of spatial features (points, lines, polygons). If x is a Spatial*DataFrame, this can be the column name of the variable to be transferred. If missing, the attribute index is used (i.e. numbers from 1 to the number of features). You can also provide a vector with the same length as the number of spatial features, or a matrix where the number of rows matches the number of spatial features

at this line:

litho1rast<-rasterize(litho1,ctmask)

you probably have to specify which column of the litho object to use in rasterization. Something like:

litho1rast<-rasterize(litho1,ctmask, field = "LITHO1")

lbusett
  • 5,801
  • 2
  • 24
  • 47
  • Hi there, thank you so much for your reply! That definitely worked to assign LITHO1 to the raster layer! – treedm Apr 30 '17 at 16:20
1

The quoted statement from Baddeley & Turner is no longer true --- that quotation is from a very old set of workshop notes.

Pixel images of class im can have factor values (since 2011). If Z is an integer-valued pixel image (of class im), you can make it into a factor-valued image by setting levels(Z) <- lev where lev is the character vector of labels for the possible values.

You should not need to use rasterize: it should be possible to convert rock[,6] directly into a pixel image using as.im (after loading the maptools package).

See the book by Baddeley, Rubak and Turner (Spatial point patterns: methodology and applications with R, CRC Press, 2016) for a full explanation.

Adrian Baddeley
  • 1,956
  • 1
  • 8
  • 7
  • Hi! thanks so much for your reply. Also it's a great book-- thorough and easy to follow! The gorillas example was very helpful. The current stumbling block is that the rock data is class SpatialPolygonsDataFrame; so far I haven't found a function that will let me convert from that to im. – treedm Apr 30 '17 at 17:09