Как прикрепить простой data.frame к SpatialPolygonDataFrame в R?

У меня (снова) проблема с объединением фреймов данных в R. Но на этот раз один — SpatialPolygonDataFrame (SPDF), а другой — обычный data.frame (DF). SPDF имеет около 1000 строк, а DF только 400. Оба имеют общий столбец QDGC.

Теперь я попытался

oo <- merge(SPDF,DF, by="QDGC", all=T)

но это приводит только к обычному кадру данных, а не к кадру данных пространственного многоугольника. Где-то читал, что это не работает, но не понял, что делать в таком случае (нужно что-то делать с колонками ID, слияние использует)

ооо такой сложный вопрос, наверное...

Спасибо! Йенс


person Jens    schedule 06.09.2010    source источник


Ответы (6)


Пусть df = фрейм данных, sp = объект пространственного полигона и by = имя или номер столбца общего столбца. Затем вы можете объединить фрейм данных с объектом sp, используя следующую строку кода

sp@data = data.frame(sp@data, df[match(sp@data[,by], df[,by]),])

Вот как работает код. Функция match внутри выравнивает столбцы так, чтобы порядок сохранялся. Поэтому, когда мы объединяем его с sp@data, порядок сохраняется правильно. Быстрая проверка того, сработал ли код, заключается в проверке двух столбцов, соответствующих общему столбцу, и проверке их идентичности (общие столбцы дублируются, и их легко удалить, но я сохраняю их такими, какие они есть). хороший чек)

person Ramnath    schedule 06.09.2010
comment
Большое спасибо! Вы спасли мой вечер! А возможно и всю неделю! Это сработало отлично. - person Jens; 06.09.2010
comment
@Ramnath Будет ли это решение работать, если фрейм пространственных данных имеет больше строк (полигонов), чем объединенные данные? А также в обратном случае - когда в объединенных данных больше наблюдений? - person radek; 13.04.2013
comment
Как это будет отличаться, если оба объекта будут SpatialP*DataFrames? - person gregmacfarlane; 24.08.2013
comment
Я думаю, вы могли бы попробовать заменить df на df@data[,by], если бы df также было SpatialP*DataFrame - person Ramnath; 24.08.2013

Это так же просто:

require(sp) # the trick is that this package must be loaded!

oo <- merge(SPDF,DF, by="QDGC")

Я испытал на себе. Но это работает, только если вы используете слияние из пакета sp. Это значение по умолчанию при загрузке пакета sp. Затем функция merge перегружается, а sp::merge используется, если первым аргументом является пространственная структура.

person Tomas    schedule 13.11.2014
comment
Это сработало очень хорошо для меня! Тем не менее, я думаю, стоит отметить, что некоторые проблемы могут возникнуть, если фрейм данных и SPDF не имеют одинакового количества строк. Я продолжал получать сообщение об ошибке (несоответствие количества объектов), вызванное этой проблемой. Наконец, я смог выполнить слияние, добавив all.x = TRUE (где x — SPDF). - person Javier Fajardo; 01.11.2017

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

Если у вас есть фрейм данных с тем же количеством строк, что и SpatialPointsDataFrame, вы можете просто напрямую заменить слот @data.

library(sp)
example(overlay) # to get the srdf object
srdf@data
spplot(srdf)
srdf@data=data.frame(x=runif(3),xx=rep(0,3))
spplot(srdf)

если вы ошиблись с количеством строк:

srdf@data=data.frame(x=runif(2),xx=rep(0,2))
spplot(srdf)
Error in data.frame(..., check.names = FALSE) : 
  arguments imply differing number of rows: 3, 2
person Spacedman    schedule 06.09.2010
comment
Хорошо, я сделал следующее: (1) oo ‹- слить(SPDF,DF, by=QDGC, all=T) (2) SPDF@data ‹- oo (3) plot(SPDF) данные теперь есть, но в очень неправильный порядок. может быть, я должен что-то сортировать? - person Jens; 06.09.2010
comment
ой. я должен был это проверить. - person Spacedman; 06.09.2010

Возможно, функция joinCountryData2Map в пакете rworldmap может дать вдохновение. (Но я могу ошибаться, как и в прошлый раз.)

person Karsten W.    schedule 06.09.2010

Еще одно решение — использовать функцию append_data из пакета tmaptools . Он вызывается с такими аргументами:

append_data(shp, data, key.shp = NULL, key.data = NULL,
  ignore.duplicates = FALSE, ignore.na = FALSE,
  fixed.order = is.null(key.data) && is.null(key.shp))

Немного прискорбно, что это называется append, так как я понимаю добавление больше в смысле rbind, и мы хотим, чтобы здесь было что-то вроде join или merge.

Игнорируя этот факт, функция действительно полезна для проверки правильности ваших соединений и наличия некоторых строк только на одной стороне соединения. Из документов:

Недостаточное покрытие (элементы формы, которые не соответствуют записям данных), избыточное покрытие (записи данных, которые не соответствуют элементам формы соответственно), а также наличие повторяющихся значений ключей автоматически проверяются и сообщаются с помощью сообщений консоли. С помощью under_coverage и over_coverage можно получить значения ключа недостаточного и избыточного покрытия из последнего вызова append_data,

person radek    schedule 02.02.2018

Если необходимо объединить два шейп-файла в один объект, просто используйте rbind().

При использовании rbind() просто убедитесь, что оба аргумента, которые вы используете, равны SpatialDataFrames. Вы можете проверить это с помощью class(sf). Если это не кадр данных, используйте st_as_sf(), чтобы преобразовать их в SpatialDataFrame, прежде чем привязывать их.

Примечание. Вы также можете использовать это для добавления к NULLs, особенно когда вы используете результат из цикла и хотите суммировать результаты.

person Jerin Mathew    schedule 05.07.2021