如何在R中将简单的数据框附加到SpatialPolygonDataFrame?

38

我在R语言中遇到了一个数据框合并的问题,其中一个是空间多边形数据框(SPDF),另一个是普通的数据框(DF)。SPDF有约1000行,而DF仅有400行。两个数据框都有一个共同的列名为QDGC。

现在,我尝试使用代码:

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

但是这只会产生一个普通的数据框,而不是一个空间多边形数据框。我在别的地方看到过,这种方法行不通,但我不明白在这种情况下应该怎么做(与ID列、合并使用有关)。
哦,这是一个很难的问题,我猜...
谢谢! Jens

在2021年,这个问题仍然很相关49032217 - garej
6个回答

49

让 df 表示数据框,sp 表示空间多边形对象,by 表示共同列的名称或列号。然后,您可以使用以下代码将数据框合并到空间多边形对象中:

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

以下是代码的工作原理。内部的match函数对齐列,因此顺序得到保留。因此,当我们与sp@data合并时,顺序被正确地保留。快速检查代码是否有效的方法是检查与公共列对应的两个列是否相同(公共列会重复出现,但我保留它作为良好的检查)。


1
非常感谢!你救了我的晚上!也可能是整个星期!它完美地运行了。 - Jens
@Ramnath 如果空间数据框的行数(多边形)比合并数据更多,这个解决方案是否有效?反之亦然 - 当连接数据中有更多观测值时呢? - radek
如果两个对象都是 SpatialP*DataFrame,那么这会有什么不同? - gregmacfarlane
如果df也是一个SpatialP*DataFrame,我认为你可以尝试用df@data[,by]替换df - Ramnath

21

就这么简单:

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

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

我已经亲自测试过了。但只有在使用merge from package sp时才有效。这是当加载sp包时的默认设置。merge函数会被重载,如果第一个参数是空间结构,则会使用sp::merge。请注意保留HTML标签。

2
这对我来说非常有效! 然而,值得指出的是,如果数据框和SPDF没有相同的行数,则可能会出现一些问题。我一直遇到一个由此问题引起的错误(“对象数量不匹配”)。 最后,通过添加“all.x = TRUE”(其中x为SPDF),我能够执行合并。 - Javier Fajardo
这太棒了,我在2021年测试过了。我的df比我的shp有更多的行,但它仍然有效。我推荐这个答案。 - wesleysc352

7

如果两个数据框没有简单的一对一映射关系,则合并可能会产生比原始数据框更多行的数据框。在这种情况下,它将不得不复制所有几何信息并创建多个多边形,这可能不是一个好事情。

如果您有一个与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

好的,我做了以下操作:(1) oo <- merge(SPDF,DF, by="QDGC", all=T) (2) SPDF@data <- oo (3) plot(SPDF) 现在数据已经在那里了,但顺序非常错误。也许我应该对某些东西进行排序? - Jens
哎呀,我应该检查一下的。 - Spacedman

2
也许 rworldmap 包中的 joinCountryData2Map 函数可以提供启发。 (但我可能错了,就像上次一样。)

0

另一种解决方案是使用tmaptools包中的append_data函数。它使用以下参数调用:

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,因为我更理解append是指rbind这样的操作,而我们想要的是类似于join或merge的操作。

尽管如此,该函数确实非常有用,可以确保您正确地进行连接,并检查某些行是否仅存在于连接的一侧。从文档中可以看到:

在覆盖范围内(形状项与数据记录不对应),在覆盖范围之上(数据记录与形状项不对应),以及重复键值的存在会通过控制台消息自动检查和报告。使用under_coverageover_coverage可以检索最后一个append_data调用的下限和上限覆盖关键值。


0
如果需要将两个 shapefile 合并为单个对象,只需使用 rbind()
在使用 rbind() 时,请确保您使用的两个参数都是 SpatialDataFrames。您可以使用 class(sf) 进行检查。如果不是数据框,则在 rbind 之前使用 st_as_sf() 将它们转换为 SpatialDataFrame
注意:您还可以使用此方法附加到 NULLs,特别是当您使用循环的结果并且想要累积结果时。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接