Агрегування точок до сітки за допомогою R


14

У мене виникає питання щодо просторової агрегації в Р. Що я намагаюся зробити, це об'єднати набір точок до сітки. Я не впевнений, як це зробити, оскільки у мене мало досвіду з подібними матеріалами. Я сподівався, що хтось із вас може мати корисні поради / можливе рішення.

Моя точка зору - це набір даних, що містить геореференційні дані про конфліктні події в Африці (див. Www.acleddata.com). Точки геореференційовані з координатами широти / довготи та містять дані про тип та час події. Що я хочу зробити, це зібрати ці точки на сітку 1x1 градуса.

Таким чином, комірка сітки повинна містити інформацію точок даних, якщо трапилася подія всередині цієї комірки сітки. Можливим продуктом цього повинен бути кадр даних або щось, що я можу експортувати у файл csv, оскільки дані призначені для використання у наборі даних панелі для статистичного аналізу.

Поки я завантажував і малював дані та файл форми, використовуючи наведений нижче код. Я вважаю, що я повинен використовувати функцію over із пакету sp для агрегації, але не знаю як. Сподіваюся, хтось із вас може допомогти.

Код , який я використовував до сих пір можна знайти тут з відповідним візуальним результатом більш ніж там .

Пропозиції щодо цього в QGIS також вітаються.


Це швидка проста операція, яка не вимагає нічого більше, ніж трохи арифметики. Але в якому форматі ви хочете вихід? "CSV" лише припускає, що це повинна бути реляційна таблиця, але це представляє проблему: коли ви збираєтеся, кожна комірка потенційно відповідає різній кількості балів. Зазвичай ви вибираєте один з двох варіантів: або виводите один запис на точку (включаючи ідентифікатор, що містить його комірку), або виводите один запис на комірку і включаєте деякі статистичні підсумки точок, які вона містить. Що вам потрібно?
whuber

1
Вибачте, я цього не уточнив. Мені потрібно один запис на клітинку . Я використовую csv-файл для створення даних панелі у форматі клітинки-року .
кінний рік

Відповіді:


13

Завантажені дані містять деякі відверті локальні помилки, тому перше, що потрібно зробити, - обмежити координати розумними значеннями:

data.df <- read.csv("f:/temp/All_Africa_1997-2011.csv", header=TRUE, sep=",",row.names=NULL)
data.df <- subset(data.df, subset=(LONGITUDE >= -180 & LATITUDE >= -90))

Обчислення координат і ідентифікаторів комірок сітки - це лише питання обрізання десяткових знаків із значень широти та довготи. (Більш загально, для довільних растрових спершу по центру їх і масштабуйте для одиничного розміру клітинок, укорочення десяткових знаків, а потім змініть масштаб і перегляньте їх у вихідне положення, як показано в коді jiнижче.) Ми можемо об'єднати ці координати в унікальні ідентифікатори, приєднавши їх до вхідного фрейму даних і випишіть доповнений кадр даних у вигляді файлу CSV. Буде один запис на бал:

ji <- function(xy, origin=c(0,0), cellsize=c(1,1)) {
  t(apply(xy, 1, function(z) cellsize/2+origin+cellsize*(floor((z - origin)/cellsize))))
}
JI <- ji(cbind(data.df$LONGITUDE, data.df$LATITUDE))
data.df$X <- JI[, 1]
data.df$Y <- JI[, 2]
data.df$Cell <- paste(data.df$X, data.df$Y)

Натомість ви хочете отримати результат, який підсумовує події в межах кожної комірки сітки. Щоб проілюструвати це, давайте обчислимо підрахунки на клітинку та виведемо ті, один запис на комірку:

counts <- by(data.df, data.df$Cell, function(d) c(d$X[1], d$Y[1], nrow(d)))
counts.m <- matrix(unlist(counts), nrow=3)
rownames(counts.m) <- c("X", "Y", "Count")
write.csv(as.data.frame(t(counts.m)), "f:/temp/grid.csv")

Для інших підсумків змініть functionаргумент у обчисленні counts. (Крім того, використовуйте програмне забезпечення для електронних таблиць або баз даних, щоб узагальнити перший вихідний файл за ідентифікатором комірок.)

Для перевірки давайте відобразимо підрахунки за допомогою центрів сітки, щоб знайти символи карти. (Точки, розташовані в Середземному морі, Європі та Атлантичному океані, мають підозрілі місця: я підозрюю, що багато з них є результатом змішування широти та довготи в процесі введення даних.)

count.max <- max(counts.m["Count",])
colors = sapply(counts.m["Count",], function(n) hsv(sqrt(n/count.max), .7, .7, .5))
plot(counts.m["X",] + 1/2, counts.m["Y",] + 1/2, cex=sqrt(counts.m["Count",]/100),
     pch = 19, col=colors,
     xlab="Longitude of cell center", ylab="Latitude of cell center",
     main="Event counts within one-degree grid cells")

Карта Африки

Цей робочий процес зараз

  • Ретельно задокументований (за допомогою самого Rкоду),

  • Відтворюється (повторно повторюючи цей код),

  • Розширювані (шляхом зміни коду очевидними способами) та

  • Розумно швидко (на всю операцію потрібно 51052 спостережень).


Код чудово відтворюється. У мене є ще одне додаткове запитання. Як замість резюме я можу приєднати інформацію з файлу вхідних даних до комірки у створеній сітці?
кінний рік

1
Це неможливо зробити з вихідною таблицею , оскільки повна інформація для комірок має змінну довжину. Правильний спосіб запису, який є першою формою виводу, я показав: один запис на точку з атрибутом ідентифікатора комірки. Один із цих двох форматів - таблиці за точкою та на комірку - очікується будь-якою статистичною програмою, яку ви використовуєте.
whuber

1
Добренько. Я бачу, що ти маєш на увазі. Потрібно лише створити сітку для всіх комірок і об'єднати її. Дякую за допомогу.
кінний рік

3

Ну, що ви хочете - це базовий, так званий, "Просторовий приєднання", який відповідає двом форматам один до одного і виділяє суму (кількість рахунку) в отриману таблицю атрибутів. Якщо ви шукаєте "Просторове приєднання в R", ви знайдете численні приклади навіть тут, на GIS.Stackexchange. Я швидко погуглився і знайшов, наприклад, цей код, розміщений у списку розсилки.

Якщо ви хочете досягти об’єднання просторового атрибуту в QGIS, виконайте наступне:

  • Збережіть свої форми як .shp файли (команда writeOGR з пакету rgdal)
  • Завантажте їх у QGIS. Відтворіть свою векторну сітку за допомогою плагіна MMQGIS (Create -> Create Grid Layer) з відповідним масштабуванням.
  • Використовуйте інструмент "Приєднатись до атрибутів" у меню "Вектор -> управління даними". Виберіть атрибут вашого точкового шару (це може бути простий стовпець, що представляє значення TRUE (1) або FALSE (0) для різних конфліктних подій).
  • Виберіть сітку та підсумуйте всі події та виконайте. Згодом я також вирізав би вашу сітку з формою африканського континенту.

Якщо приєднання якось не вдається (не працює для мене кожен раз), тоді дотримуйтесь SEXTANTE і шукайте панель інструментів SAGA, яка також має дуже хороші функції приєднання.


Хоча це рішення, воно є особливо складним і неефективним, враховуючи, що підсумовування точок до сітки є лише справою декількох простих арифметичних операцій, що є найкращим R. Використання rgdalформ- файлів, QGIS та Sextante трохи схоже на те, щоб рекомендувати кому-небудь найняти сучасний автоматизований промисловий завод, щоб скріпити дві дошки разом :-).
whuber

Я спробую такий підхід у ці вихідні. Найближчим часом я можу захотіти комбінувати різні файли форм між собою, щоб це могло бути корисним. Дякуємо за вклад та пропозиції.
кінний рік

@whuber: Це правда, але якщо ви хочете розповсюджувати та, можливо, стилізувати свій результат, то очевидний вибір є форм-файл. Тим не менше, приємний R приклад!
Curlew

Нарешті я спробував це. Але проблема такого підходу полягає в тому, що він підводить всі спостереження до полігону. Хоча в ідеалі я хочу зберігати інформацію про різні події протягом часу. Але може бути, що я щось зробив не так.
кінські роки
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.