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.