Властивості 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але я збентежений , який оператор @, $, []використовувати для доступу їх або змінити їх.


1
Оскільки це справді питання щодо Rсинтаксису, це не стосується spпакету чи його об'єктів. Rвстановлюється з підручника: починайте там, з ваших досліджень. Інтернет та друковані ЗМІ пропонують безліч додаткових ресурсів для навчання R.
whuber

Відповіді:


21

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

Наявні слоти та організація їх залежить від того, який тип класу характеристик представлений. Об'єкти 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, швидше за все, стане новим стандартом для просторових об'єктів у Р. Детальний опис цього класу можна прочитати в CRAN sf сайт Простий Можливості для R .


Дякую за детальне пояснення того, що відбувається за лаштунками. Здається, що для оператора SpatialPointsDataFrameможна отримати не тільки стовпці @data, але й стовпці @coords $без необхідності виклику слота @coords. Так sdat@coords$eastingдає такий же результат, як і sdat$easting.
jirikadlec2

Схоже, ви викликаєте стовпець у <at> даних. Це не те саме, що слот <at> для координат. Ви помітите, що якщо ви зателефонуєте до імен стовпців (sdat <at> coords), ви повернете назви стовпців матриці: "coords.x1", "coords.x2". Не потрібно утримувати координати у кадрі даних і, оскільки це дублюється, талія пам’яті.
Джеффрі Еванс

Ні. Я не називаю стовпець у <at> даних. Використовуючи SpatialPointsDataFrame з мого зразкового сценарію, colnames(locations@coords)повертається, [1] "x" "y"але colnames(locations@data)повертається [1] "v1" "v2". Може бути, поведінка залежить від того, яка функція була використана для створення SpatialPointsDataFrame?
jirikadlec2

Насправді у моєму першому коментарі є помилка. sdat@coords$eastingне працює, тому що sdat @ coords є матрицею. Але sdat@coords[,"easting"]еквівалентно sdat@coords[,1]і до sdat$easting.
jirikadlec2

Один застереження, Colnames () використовується для повернення імен стовпців у матриці, тоді як, імена () повертають NULL. Хоча, і імена (), і імена () будуть працювати над об'єктом фрейму даних, таким як <at> дані. Найкращий спосіб отримати дані з <at> матриці координат - це його індексувати: sdat <at> coords [, 1] або за назвою стовпця sdat <at> coords [, "coords.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$northingдає мені y-координатний вектор.
jirikadlec2

Я думаю, якимось чином R розглядає два стовпчики для координат як ще два стовпчики частини фрейму даних SpatialPointsDataFrame. Ось чому ви можете мати стовпчик з такою ж назвою всередині слота @data
Гільєрмо Ольмедо,

1
Здається, що іменування стовпців у @coordsматриці символу SpatialPointsDataFrameзалежить від того, як створений SpatialPointsDataFrameоб'єкт. Перший спосіб: coordinates(sdat) <- x ~ yперейменує стовпці в "coords.x1", "coords.x2". Спосіб другий: sdat <- SpatialPointsDataFrame(xy, attributes)збереже початкові назви стовпців з xyматриці.
jirikadlec2
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.