Агрегирование точек в сетку с использованием R

14

У меня есть вопрос относительно пространственной агрегации в R. Что я пытаюсь сделать, это агрегировать точечный набор данных в сетку. Однако я не уверен, как это сделать, поскольку у меня мало опыта с подобными вещами. Я надеялся, что у кого-нибудь из вас может быть полезное руководство / возможное решение.

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

Таким образом, ячейка сетки должна содержать информацию о точках данных, если событие произошло в этой ячейке сетки. Конечным продуктом этого должен быть фрейм данных или что-то, что я могу экспортировать в CSV-файл, так как данные предназначены для использования в наборе данных панели для статистического анализа.

До сих пор я загружал и наносил на график данные и шейп-файл, используя код ниже. Я считаю, что я должен использовать функцию over из пакета sp для агрегирования, но я не знаю как. Надеюсь, один из вас может помочь.

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

Предложение для этого в QGIS также приветствуется.

horseoftheyear
источник
Это быстрая простая операция, не требующая ничего, кроме небольшой арифметики. Но в каком формате вы хотите вывод? «CSV» указывает только на то, что это должна быть реляционная таблица, но это представляет проблему: когда вы агрегируете, каждая ячейка потенциально соответствует разному количеству точек. Обычно вы выбираете один из двух вариантов: либо выводите одну запись на точку (включая идентификатор содержащей ее ячейки), либо вы выводите одну запись на ячейку и включаете некоторые статистические сводки точек, которые она содержит. Что вам нужно?
whuber
1
Извините, я не уточнил это. Мне нужна одна запись на ячейку . Я использую CSV-файл, чтобы сделать данные панели в формате ячейки-года .
horseoftheyear

Ответы:

12

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

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кода),

  • Воспроизводимый (путем повторного запуска этого кода),

  • Расширяемый (изменяя код очевидными способами), и

  • Разумно быстро (вся операция занимает менее 10 секунд для обработки этих 53052 наблюдений).

Whuber
источник
Код прекрасно воспроизводится. У меня есть еще один вопрос. Вместо сводки, как мне прикрепить информацию из файла входных данных к ячейке в созданной сетке?
horseoftheyear
1
Это невозможно сделать с выходной таблицей , поскольку полная информация для ячеек имеет переменную длину. Правильный способ записи с первой формой вывода, который я показал: одна запись на точку с атрибутом идентификатора ячейки. Один из этих двух форматов - таблицы для каждой точки и для каждой ячейки - будет использоваться любой статистической программой, которую вы используете.
whuber
1
Ах хорошо. Я понимаю что ты имеешь ввиду. Нужно только создать сетку для всех ячеек и объединить ее. Спасибо за помощь.
horseoftheyear
3

Ну, что вам нужно, так это базовое так называемое «Пространственное соединение», которое сопоставляет два шейп-файла друг с другом и распределяет сумму (число счетчиков) в результирующей таблице атрибутов. Если вы ищете «Пространственное соединение в R», вы найдете множество примеров даже здесь, на GIS.Stackexchange. Я быстро погуглил и нашел, например, этот код, размещенный в списке рассылки.

Если вы хотите добиться объединения пространственных атрибутов в QGIS, выполните следующие действия:

  • Сохраните ваши фигуры как файлы .shp (команда writeOGR из пакета rgdal)
  • Загрузите их в QGIS. Воссоздайте векторную сетку с помощью плагина MMQGIS (Создать -> Создать слой сетки) с соответствующим масштабированием.
  • Используйте инструмент «Атрибуты соединения» из меню Вектор -> Управление данными. Выберите атрибут вашего точечного слоя (это может быть простой столбец, представляющий значения TRUE (1) или FALSE (0) для различных конфликтных событий).
  • Выберите свою сетку и суммируйте все вхождения и выполните. После этого я бы обрезал вашу сетку по форме африканского континента.

Если соединение как-то не получается (у меня не работает каждый раз), тогда придерживайтесь SEXTANTE и ищите набор инструментов SAGA, который также имеет очень хорошие функции соединения.

кроншнеп
источник
Хотя это решение, оно особенно сложное и неэффективное, учитывая, что суммирование точек на сетке - это всего лишь вопрос нескольких простых арифметических операций, которые Rпревосходят в. Использование шейп-файлов, rgdalQGIS и Sextante - это все равно, что рекомендовать кому-то арендовать современное автоматизированное промышленное предприятие, чтобы склеить две доски :-).
whuber
Я попробую этот подход в эти выходные. В ближайшем будущем я могу захотеть объединить различные файлы форм друг с другом, так что это может быть полезно. Спасибо за вклад и предложения.
horseoftheyear
@whuber: Это правда, но если вы хотите распространять и, возможно, стилизовать свой вывод, то шейп-файл является очевидным выбором. Тем не менее, хороший пример R!
Curlew
Я наконец попробовал это. Но проблема этого подхода состоит в том, что он суммирует все наблюдения в многоугольник. Хотя я в идеале хочу сохранить информацию о разных событиях со временем. Но могло случиться так, что я сделал что-то не так.
год