Как прикрепить простой data.frame к SpatialPolygonDataFrame в R?
У меня (опять же) проблема с объединением фреймов данных в R. Но на этот раз один SpatialPolygonDataFrame (SPDF
) а другой обычный data.frame (DF
). SPDF
имеет около 1000 строк DF
только 400. Оба имеют общий столбец, QDGC
Теперь я попробовал
oo <- merge(SPDF,DF, by="QDGC", all=T)
но это приводит только к нормальному data.frame, а не к пространственному фрейму данных многоугольника. Я читал где-то еще, что это не работает, но я не понимал, что делать в таком случае (должен что-то делать со столбцами идентификаторов, слияния использует)
ооо, такой сложный вопрос, я задаю вопрос...
Спасибо! Jens
6 ответов
Пусть df = фрейм данных, sp = пространственный объект многоугольника и by = имя или номер столбца общего столбца. Затем вы можете объединить фрейм данных в объект sp, используя следующую строку кода
sp@data = data.frame(sp@data, df[match(sp@data[,by], df[,by]),])
Вот как работает код. Функция match внутри выравнивает столбцы так, чтобы порядок сохранялся. Поэтому, когда мы объединяем его с sp @ data, порядок сохраняется правильно. Быстрая проверка, чтобы увидеть, сработал ли код, заключается в проверке двух столбцов, соответствующих общему столбцу, и определении их идентичности (общие столбцы дублируются, и копию легко удалить, но я сохраняю ее, так как хорошая проверка)
Это так просто, как это:
require(sp) # the trick is that this package must be loaded!
oo <- merge(SPDF,DF, by="QDGC")
Я проверял сам. Но это работает, только если вы используете merge из пакета sp. Это по умолчанию, когда sp
пакет загружен. merge
функция затем перегружается и sp::merge
используется, если первый аргумент - пространственная структура.
Слияние может привести к созданию кадра данных с большим количеством строк, чем в оригиналах, если нет простого сопоставления 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
Может быть, функция joinCountryData2Map
в пакете rworldmap может дать вдохновение. (Но я могу ошибаться, как и в прошлый раз.)
Еще одно решение заключается в использовании 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))
Это немного прискорбно, что это называется добавление, так как я понимаю, добавление больше в смысле rbind
и мы хотим что-то вроде join
или же merge
Вот.
Игнорируя этот факт, функция действительно полезна для проверки правильности ваших объединений и наличия некоторых строк только на одной стороне объединения. Из документов:
Под покрытием (элементы формы, которые не соответствуют записям данных), с избыточным покрытием (записи данных, которые не соответствуют элементам формы соответственно), а также с наличием дублированных значений ключей, автоматически проверяются и сообщаются через консольные сообщения. С
under_coverage
а такжеover_coverage
могут быть извлечены значения ключа покрытия "под" и "поверх" из последнего вызова append_data,
Если необходимо объединить два шейп-файла в один объект, просто используйте.
Когда используешь
rbind()
, просто убедитесь, что оба аргумента, которые вы используете,
SpatialDataFrames
. Вы можете проверить это, используя
class(sf)
. Если это не фрейм данных, используйте
st_as_sf()
преобразовать их в
SpatialDataFrame
прежде чем связывать их.
Примечание: вы также можете использовать это, чтобы добавить к
NULLs
, особенно когда вы используете результат цикла и хотите суммировать результаты.