SpatialPoints и SpatialPointsDataframe

Работа с пакетом sp в R. Интересно, когда бы я использовал SpatialPoints, а когда SpatialPointsDataframe. Мне так кажется, что нет большой разницы?!

Разница лишь в том, что в SpatialPointsDataframe я могу хранить больше атрибутов?! Если это так, могу ли я создать SpatialPointDataframe из существующего Dataframe (если в этом кадре существуют координаты) без обхода создания пространственных точек?

1 ответ

Решение

Объекты SpatialPoints и SpatialPointsDataFrame являются объектами S4. Это правда, что основное структурное отличие состоит в том, что в последнем есть дополнительный слот, содержащий данные атрибутов. Однако практические различия более значительны. Просто чтобы привести несколько примеров (используя встроенный meuse база данных из пакета sp, содержащий данные геокодирования загрязнений из поймы реки Мёз).

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"

Даже если meuse является SpatialPointsDataFrame, мы все еще можем индексировать его, как если бы это был простой data.frame. Обратите внимание, как мы ссылаемся на lead столбец таблицы атрибутов, как будто meuse был DF, и обратите внимание, как индексация работает, как это происходит в 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

Мы также можем использовать метод plot для SpatialPointsDataFrames для построения графика данных.

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)

И мы можем преобразовать координаты во что-то более полезное (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)

И, наконец, контрпример, накладывающий точки на карту Google:

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)))

То, что мы сделали здесь, по сути, является преобразованием meuse от data.frame до пространственного PointsDataFrame, чтобы мы могли использовать spTransform(...) на координаты, а затем преобразовать результат обратно в data.frame, чтобы мы могли использовать ggplot наложить их на карту Google.

Другие вопросы по тегам