SpatialPoints and SpatialPointsDataframe
Asked Answered
P

1

17

Working with the sp package in R. I wonder when I would use SpatialPoints and when SpatialPointsDataframe. It seems so me that there is not much difference?!

Is the only difference that in a SpatialPointsDataframe I can store more attributes?! If so, can I create a SpatialPointDataframe from an existing Dataframe (if coordinates are exisiting in this dataframe) without taking the detour of creating spatialPoints?

Preposterous answered 26/8, 2015 at 14:32 Comment(1)
You can use coordinates(Dataframe) <- c(easting, northing) to set the coordinates of an existing dataframe. This will make the dataframe a spatial object. Here, easting and northing are the column names in Dataframe. You may also want to set the projection using proj4string.Warrigal
S
18

Both SpatialPoints and SpatialPointsDataFrame objects are S4 objects. It is true that the main structural difference is that, in the latter, there is an extra slot containing the attributes data. However the practical differences more significant. Just to give a few examples (using the built-in meuse database from package sp, containing geocoded contaminant data from the floodplain of the river Meuse).

library(sp)
data(meuse)
class(meuse)        # a data.frame
# [1] "data.frame"
head(meuse[,1:5])   # first 5 columns
#        x      y cadmium copper lead
# 1 181072 333611    11.7     85  299
# 2 181025 333558     8.6     81  277
# 3 181165 333537     6.5     68  199
# 4 181298 333484     2.6     81  116
# 5 181307 333330     2.8     48  117
# 6 181390 333260     3.0     61  137

coordinates(meuse) <- 1:2     # convert to spDF object; use first 2 columns for lon/lat
class(meuse)                  # now a SpatialPointsDataFrame
# [1] "SpatialPointsDataFrame"
# attr(,"package")
# [1] "sp"

Even though meuse is a SpatialPointsDataFrame, we can still index it as if it was a simple data.frame. Notice how we refer to the lead column of the attributes table as if meuse was a df, and notice how indexing works as it does in a df.

meuse[meuse$lead>500,1:5]        # high lead
#         coordinates cadmium copper lead zinc elev
# 55 (179973, 332255)    12.0    117  654 1839 7.90
# 60 (180100, 332213)    10.9     90  541 1571 6.68
meuse[meuse$lead<40,1:5]         # low lead
#              coordinates cadmium copper lead zinc  elev
# 112 (180328, 331158)     0.4     20   39  113 9.717
# 161 (180201, 331160)     0.8     18   37  126 9.036

We can also use the plot method for SpatialPointsDataFrames to plot the data.

par(mfrow=c(1,2), mar=c(2,2,2,2))    # 1 X 2 grid of plots; remove margins
plot(meuse, pch=20, main="Full Dataset", axes=TRUE)
plot(meuse, 
     bg=rev(heat.colors(5))[cut(meuse$lead,breaks=c(0,100,200,300,400,Inf),labels=FALSE)],
     col="grey",main="Lead Distribution", pch=21, axes=TRUE)

And we can transform the coordinates into something more useful (lon/lat).

library(rgdal)
proj4string(meuse) <- CRS("+init=epsg:28992")                   # set original projection
meuse <- spTransform(meuse, CRS("+proj=longlat +datum=WGS84"))  # transform to lon/lat
plot(meuse, pch=20, main="Full Dataset", axes=TRUE)
plot(meuse, 
     bg=rev(heat.colors(5))[cut(meuse$lead,breaks=c(0,100,200,300,400,Inf),labels=FALSE)],
     col="grey",main="Lead Distribution", pch=21, axes=TRUE)

And finally a counter-example, overlaying the points onto a Google map:

library(ggmap)    # loads ggplot2 as well
map <- get_map(location=rowMeans(bbox(meuse)), zoom=13)   # get Google map
ggmap(map) + 
  geom_point(data=as.data.frame(meuse), aes(x,y,fill=lead), 
             color="grey70", size=3.5, shape=21)+
  scale_fill_gradientn(colours=rev(heat.colors(5)))

What we've done here, in essence, is convert meuse from a data.frame to a spatialPointsDataFrame so that we could use spTransform(...) on the coordinates, then convert the result back to a data.frame so that we can use ggplot to overlay them onto a Google map.

Snailfish answered 26/8, 2015 at 20:5 Comment(1)
Thanks for that awesome explanation. I am a little bit lost in the documentation of the sp package and find it hard to come by good explanation/tutorials online! I hope that will be found by others!Preposterous

© 2022 - 2024 — McMap. All rights reserved.