Ответ 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.