使用R将点聚集到网格


14

我对R中的空间聚合有一个疑问。我想做的是将点数据集聚合到网格中。但是我不确定如何执行此操作,因为我对此类材料缺乏经验。我希望你们中的每个人都可以得到一些有用的指导/可能的解决方案。

我的优势是一个包含有关非洲冲突事件的地理参考数据的数据集(请参见www.acleddata.com)。这些点通过纬度/经度坐标进行地理参考,并包含有关事件类型和时间的数据。我想要做的是将这些点聚合到1x1度的网格中。

因此,如果某个事件发生在该网格单元中,则该网格单元应包含数据点的信息。最终的结果应该是数据框或可以导出到csv文件的东西,因为该数据打算用于面板数据集中以进行统计分析。

到目前为止,我已使用以下代码加载并绘制了数据和shapefile。我相信我应该使用sp包中的over函数进行聚合,但是我不知道如何做。希望你们中的一个能提供帮助。

我至今使用的代码,可以发现这里有超过相应的视觉效果存在

也欢迎在QGIS中提出此建议。


这是一个快速简单的操作,只需要一点算术即可。但是,您想要哪种格式的输出?“ CSV”仅表明它应该是一个关系表,但这会带来一个问题:聚合时,每个单元格都可能对应于不同数量的点。通常,您选择以下两个选项之一:您可以为每个输出一条记录(包括其包含的单元格的ID),或者为每个单元格输出一条记录,并包含其包含的点的一些统计摘要。你需要哪一个?
whuber

1
抱歉,我没有指定。我需要的是每个单元一个记录。我使用csv文件以cell-year格式制作面板数据。
horseoftheyear 2013年

Answers:


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代码本身),

  • 可复制(通过重新运行此代码),

  • 可扩展的(通过以明显的方式修改代码),以及

  • 相当快(整个操作花费不到10秒来处理这53052个观测值)。


代码是完全可复制的。我还有一个问题。而不是摘要,如何将信息从输入数据文件附加到创建的网格中的单元格?
horseoftheyear

1
这与输出是不可能的,因为单元的完整信息具有可变的长度。我展示的第一种输出形式的正确记录方式是:每点具有单元标识符属性的一条记录。无论使用哪种统计程序,都希望使用这两种格式之一(按点和按单元格表)。
whuber

1
喔好吧。我明白你的意思了。只需为所有单元格创建一个网格并将其合并即可。谢谢您的帮助。
horseoftheyear 2013年

3

好吧,您想要的是一个基本的所谓的“空间连接”,它将两个shapefile彼此匹配,并将总和(计数)分配给结果属性表。如果搜索“ R中的空间连接”,那么即使在GIS.Stackexchange上,您也可以找到许多示例。我迅速搜索了一下,发现例如将此代码发布在邮件列表中。

如果要在QGIS中实现空间属性联接,请执行以下操作:

  • 将形状另存为.shp文件(来自rgdal软件包的命令writeOGR
  • 将它们加载到QGIS中。通过MMQGIS插件(创建->创建网格层)以适当的比例重新创建矢量网格。
  • 使用“向量”->“数据管理”菜单中的“联接属性”工具。选择点图层的属性(这可以是代表不同冲突事件的TRUE(1)或FALSE(0)值的简单列)。
  • 选择您的网格并汇总所有事件并执行。之后,我还将用非洲大陆的形状修剪您的网格。

如果Join某种程度上失败了(不是每次都对我不起作用),请坚持使用SEXTANTE并查找SAGA工具箱,该工具箱也具有非常好的联接功能。


尽管这是一种解决方案,但鉴于将点汇总到网格只是一些简单的算术运算(R擅长于此)的问题,所以它是一种特别复杂且效率低的解决方案。使用shapefile 、、rgdalQGIS和Sextante有点像建议有人租用现代化的自动化工厂来将两块板钉在一起:-)。
whuber

我将在本周末尝试这种方法。在不久的将来,我可能希望将各种形状文件相互组合,这样可能会很有用。感谢您的输入和建议。
horseoftheyear 2013年

@whuber:是的,但是如果您想分发输出并设置其样式,那么shapefile是显而易见的选择。尽管如此,还是不​​错的R示例!
Curlew

我终于尝试了。但是这种方法的问题在于,它会将所有观测值求和。虽然我理想情况下希望随时间推移保留有关不同事件的信息。但这可能是我做错了。
horseoftheyear 2013年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.