Свойства и операторы SpatialPointsDataFrame в R

14

Я создал объект типа SpatialPointsDataFrameс использованием spпакета в R. Однако я не совсем понимаю, @, $, . and []когда нужно использовать операторы для доступа к различным свойствам моего объекта. Вот мой пример кода:

library(sp)
library(rgdal)

#creating a SpatialPointsDataFrame with sample points in UTM
x <- c(15.2, 15.3, 15.4, 15.5, 15.7)
y <- c(50.4, 50.2, 50.3, 50.1, 50.4)
v1 <- c(1.0, 2.0, 3.0, 4.0, 5.0)
v2 <- c("a","b","b","c","a")
attributes <- as.data.frame(cbind(v1,v2))
xy <- cbind(x,y)
locationsDD <- SpatialPointsDataFrame(xy, attributes)
proj4string(locationsDD) <- CRS("+proj=longlat")
locations <- spTransform(locationsDD, CRS("+proj=utm +zone=33"))
plot(locations)

#using the different operators: WHEN TO USE @, $ or [] ?

#all these work!
property1 <- locations$v1
property2 <- locations@data$v1
property3 <- locations@data[,"v1"]
property4 <- locations@data["v1"]

#these also work
property5 <- locations@coords
property6 <- locations@bbox
property7 <- locations@coords[,2]

#these three work only in my special case
property8 <- locations@coords[,"y"]
property9 <- locations$x
property10 <- locations$y

#these don't work: $ operator is invalid for atomic vectors
property11 <- locations@coords$x
property12 <- locations@coords$y

Кто-нибудь может мне помочь, когда использовать @, $, []операторы? Когда я пытаюсь прочитать документацию, ?SpatialPointsDataFrameя вижу различные свойства, такие как coordsили, bboxно я не понимаю, какой оператор @, $, []использовать для доступа к ним или их изменения.

jirikadlec2
источник
1
Поскольку это действительно вопрос Rсинтаксиса, он не относится к spпакету или его объектам. Rустанавливается с помощью учебника: начните с исследования. Сеть и печатные СМИ предлагают множество дополнительных ресурсов для обучения R.
whuber

Ответы:

21

Пространственные sp-данные являются объектами класса S4 и состоят из слотов (называемых с помощью @), которые содержат компоненты представляемого класса пространственных объектов (например, @data содержит атрибуты, @coords содержат пары координат и т. Д.). Вы можете вернуть имена слотов верхнего уровня с помощью slotNames (), но они не являются рекурсивными и не будут возвращать имена вложенных слотов для объектов класса многоугольника. Каждый слот может содержать свой класс объектов, и, прежде чем работать с ним, его следует проверить с помощью str () или class (). Слот @data всегда является объектом data.frame, а @coords - матрицей, тогда как @polygons является объектом списка с дополнительными слотами (labpt, area, hole, ringDir и координаты).

Доступные слоты и их организация зависят от того, какой тип класса объектов представлен. Объекты SpatialPointsDataFrame являются наиболее основными, тогда как объекты SpatialPolygonsDataFrame имеют вложенность (как показано выше). Эта вложенная структура, представляющая каждый многоугольник, должна учитываться с использованием чего-то вроде sapply для работы с каждым объектом списка (многоугольником).

Вот пример, который использует sapply, чтобы вернуть площадь для каждого многоугольника, итерируя по «многоугольникам», а затем по вложенным слотам «области».

sapply(slot(sdat, 'polygons'), function(i) slot(i, 'area')) 

В случае объектов многоугольника, поскольку они хранятся в виде списка для каждого многоугольника, вы можете альтернативно использовать индексацию списка. Вот пример возврата первого многоугольника (в результате получается объект класса «Polygon», а не SpatialPolygonsDataFrame):

sdat@polygons[[1]]

В более поздних версиях sp разработчики начали, в некоторых случаях, устраняя необходимость прямого вызова слота @data.

Например, для индексации @data вы ранее:

sdat@data[sdat@data$att >= 0.5 ,]  

и сейчас:

sdat[sdat$att >= 0.5 ,]

Однако, как указывалось ранее, это не относится к другим слотам (например, координатам, полигонам и т. Д.). Что касается того, когда использовать [] или $, это все еще зависит от типа операции. Скобки «[]» могут использоваться для вызова имени в кадре данных, но в основном используются для индексации, тогда как $ специально используется для вызова столбца в кадре данных. Причина, по которой работает «косвенный» вызов имени столбца, заключается в том, что разработчики добавили функциональность, позволяющую осуществлять рекурсивный поиск по объекту sp. Однако, чтобы избежать конфликтов имен (как в вашем примере; наличие столбцов x, y в вашем кадре данных будет конфликтовать с именами x, y в именах матрицы @coord), существует некоторая внутренняя проверка согласованности, объясняющая, почему это работает только в некоторых экземпляров.

Одна удобная характеристика заключается в том, что вы можете подмножество пространственного объекта через индекс строки. Здесь я подгруппирую первые 10 объектов.

sub.sdat <- sdat[1:10,] 

Или, альтернативно, случайная выборка (n = 10) с использованием вектора индекса строки.

rs.sdat <- sdat[sample(1:nrow(sdat), 10),]

Понимание индексации и использования скобок - очень важная вещь при написании кода на языке R.

Редактирование (24.03.2017): Обратите внимание, что класс простых объектов (sf), следуя стандарту GeoJSON, скорее всего, станет новым стандартом для пространственных объектов в R. Подробное описание этого класса можно прочитать на сайте CRAN sf. сайт Простой Возможности для R .

Джеффри Эванс
источник
Спасибо за подробное объяснение того, что происходит за кулисами. Похоже, что SpatialPointsDataFrameне только столбцы @data, но и столбцы @coords могут быть получены $оператором без необходимости вызывать слот @coords. Так что sdat@coords$eastingдает тот же результат, что и sdat$easting.
jirikadlec2
Похоже, вы вызываете столбец в <at> данных. Это не то же самое, что слот <at> координировать. Вы заметите, что если вы вызываете colnames (sdat <at> ords), вы будете возвращать имена столбцов матрицы: "ordins.x1 ", "ordins.x2". Нет необходимости хранить координаты в кадре данных и, поскольку он дублируется, объем памяти.
Джеффри Эванс
Я не вызываю столбец в данных <at>. Использование SpatialPointsDataFrame из моего примера сценария colnames(locations@coords)возвращает, [1] "x" "y"но colnames(locations@data)возвращает [1] "v1" "v2". Может быть, поведение зависит от того, какая функция использовалась для создания SpatialPointsDataFrame?
jirikadlec2
На самом деле у меня есть ошибка в моем первом комментарии. sdat@coords$eastingне работает, потому что sdat @ordins - это матрица. Но sdat@coords[,"easting"]эквивалентно sdat@coords[,1]и sdat$easting.
jirikadlec2
Одно предостережение: colnames () используется для возврата имен столбцов в матрице, тогда как names () возвращает NULL. Хотя и names (), и colnames () будут работать с объектом dataframe, таким как <at> data. Лучший способ извлечь данные из матрицы координат <at> - это проиндексировать их: sdat <at> ords [, 1] или по имени столбца sdat <at >ordins [, "ordins.x1 "], но, как вы заметили, $ делает не работает, потому что это матричный объект.
Джеффри Эванс
4

Вы должны попытаться str(locations)уточнить это.

например, они правильные:

property2 <- locations@data$v1
property5 <- locations@coords
property6 <- locations@bbox
property7 <- locations@coords[,"x"]
property8 <- locations@coords[,2]

И этот property1 <- locations$v1работает, потому что он ссылается на data.frame внутри местоположения, @data

Гильермо Олмедо
источник
str(locations)дал мне несколько хороших советов. Теперь я понимаю, что @используется для «слота класса». Но я до сих пор не понимаю, почему property9 <- locations$xработает, когда names(locations)не содержит ни одного столбца с именемx
jirikadlec2
1
Когда вы создаете SpatialPointDataFrame, вы назначаете x и y в качестве имен координат. Если вы посмотрите на местоположения @ координаты, вы можете увидеть матрицу с координатами. Кроме того, если вы попытаетесь создать новый столбец в @data с именем «x», вы не сможете этого сделать, поскольку его уже используют в качестве имени координаты.
Гильермо Олмедо
Я до сих пор не понимаю, какую «магию» SpatialPointsDataFrameиспользует объект для доступа к координатам с помощью $оператора. Но, по крайней мере, сейчас мне удобнее пользоваться им. Я запустил следующий код: colnames(locations@coords) <- c("easting","northing") после того, как я запустил его, locations$eastingмне дается вектор координаты x и вектор locations$northingy.
jirikadlec2
Я думаю, что в некотором роде R рассматривает два столбца для координат как еще два столбца части кадра данных SpatialPointsDataFrame. Вот почему вы можете иметь столбец с тем же именем внутри слота @data
Гильермо
1
Кажется, что наименование столбцов в @coordsматрице SpatialPointsDataFrameзависит от того, как SpatialPointsDataFrameбыл создан объект. Способ первый: coordinates(sdat) <- x ~ yпереименуем столбцы в "coords.x1", "coords.x2". Способ второй: sdat <- SpatialPointsDataFrame(xy, attributes)сохранит исходные имена столбцов из xyматрицы.
jirikadlec2