Подтвердить что ты не робот

SpatialPoints и SpatialPointsDataframe

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

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

4b9b3361

Ответ 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 в пространственный топографический шаблон, чтобы мы могли использовать spTransform(...) в координатах, а затем преобразовать результат обратно в data.frame, чтобы мы можем использовать ggplot, чтобы наложить их на карту Google.