我有一个地理参考事件数据集,位于以下格式的数据框中:
LONGITUDE LATITUDE VAR1
33.4 4.4 5
33.4 4.4 3
33.4 4.4 1
30.4 4.2 2
28.4 5.1 2
它计算了地理参考事件中的死亡人数。除此之外,我有一个国家的省份形状文件,如下:
> str(shapefile)
'data.frame': 216 obs. of 5 variables:
$ CONSTI_COD: num 1 2 3 4 5 6 7 8 9 10 ...
$ Area : num 20 11.7 10.7 223.3 38.7 ...
$ PROVINCE_NAME : Factor w/ 216 levels "CENTRAL","COAST",..: 4 4 4 4 4 4 4 4 2 2 ...
$ Shape_Leng: num 0.193 0.152 0.201 0.872 0.441 ...
$ Shape_Area: num 0.001628 0.000947 0.000867 0.018135 0.003145 ...
..@ polygons :List of 216
.. ..$ :Formal class 'Polygons' [package "sp"] with 5 slots
.. .. .. ..@ Polygons :List of 1
.. .. .. .. ..$ :Formal class 'Polygon' [package "sp"] with 5 slots
.. .. .. .. .. .. ..@ labpt : num [1:2] 36.9 -1.3
.. .. .. .. .. .. ..@ area : num 0.00163
.. .. .. .. .. .. ..@ hole : logi FALSE
.. .. .. .. .. .. ..@ ringDir: int 1
.. .. .. .. .. .. ..@ coords : num [1:151, 1:2] 36.8 36.8 36.8 36.9 36.9 ...
.. .. .. ..@ plotOrder: int 1
.. .. .. ..@ labpt : num [1:2] 36.9 -1.3
.. .. .. ..@ ID : chr "0"
.. .. .. ..@ area : num 0.00163
[...etc]
我需要做的是将事件数据放在省内,即根据坐标在第一个数据框中添加第四列,该数据框说明每个事件发生在哪个省。所以我会有这样的事情:
LONGITUDE LATITUDE VAR1 PROVINCE
33.4 4.4 5 CENTRAL
33.4 4.4 3 CENTRAL
33.4 4.4 1 CENTRAL
30.4 4.2 2 COAST
28.4 5.1 2 COAST
这是真的吗?我想我前段时间发现了一篇解释如何执行此操作的帖子(Stack Overflow之外),但我现在找不到它。
谢谢!
(对不起,如果这里有类似的问题。我进行了搜索,但我没有找到答案,也许是因为我不知道我在寻找什么。我非常感谢链接到类似的帖子。)
答案 0 :(得分:5)
你所谈论的是一个"空间连接" (或"空间交叉"或"覆盖")。借助over
包中的sp
函数,这非常简单。
以下是一个例子。
首先,让我们下载并导入世界各国的多边形形状文件。
download.file(paste0('http://www.naturalearthdata.com/http//',
'www.naturalearthdata.com/download/110m/cultural/',
'ne_110m_admin_0_countries.zip'),
f <- tempfile())
unzip(f, exdir=tempdir())
library(rgdal)
countries <- readOGR(tempdir(), 'ne_110m_admin_0_countries')
现在我们将创建一些落在多边形shapefile范围内的随机坐标数据。然后,我们将列x
和y
定义为coordinates
,并为多边形分配相同的CRS(尽管您的数据可能不是这样;请务必指定正确的坐标系)。
pts <- data.frame(x=runif(10, -180, 180), y=runif(10, -90, 90),
VAR1=LETTERS[1:10])
coordinates(pts) <- ~x+y # pts needs to be a data.frame for this to work
proj4string(pts) <- proj4string(countries)
plot(countries)
points(pts, pch=20, col='red')
现在我们可以执行空间叠加:
over(pts, countries)$admin
# [1] <NA> <NA> Turkey <NA>
# [5] Macedonia <NA> China Argentina
# [9] <NA> Canada
# 177 Levels: Afghanistan Albania ... Zimbabwe
请注意,在这种情况下,一些随机点落在海洋中(即外部多边形)。与多边形对象相交时,这些点返回NA。
现在我们cbind
pts
所需的属性:
cbind.data.frame(pts, country=over(pts, countries)$admin)
# x y VAR1 country
# 1 -52.59404 -37.422879 A <NA>
# 2 -33.88867 -40.194482 B <NA>
# 3 38.84383 37.272460 C Turkey
# 4 -84.04949 7.118878 D <NA>
# 5 20.98272 40.920470 E Macedonia
# 6 -155.32951 -37.612497 F <NA>
# 7 99.40166 38.630049 G China
# 8 -61.84025 -27.412885 H Argentina
# 9 -37.65287 -3.666080 I <NA>
# 10 -112.81197 59.959475 J Canada