数据
我有两个形状文件标记了巴基斯坦national和provincial选举选区的界限。
目标
我正在尝试使用R来创建一个密钥,该密钥将根据这些数据中的坐标生成一个列表,其中包含哪些省级选区“包含在内”或与哪些国家级选区交叉。例如,NA-01对应于PA-01,PA-02,PA-03; NA-02对应于PA-04和PA-05等(关键将最终用于链接包含国家和省级选举结果的单独数据帧;我已经找到了这一部分。)
我只有通过反复试验获得的基本/中级R技能,没有使用R以外的GIS数据的经验。
尝试的解决方案
我能找到的最接近这个问题的解决方案是this guide来计算R中的交叉区域。但是,我无法成功复制三种提议方法中的任何一种(提问者使用一般的TRUE) / FALSE报告交叉点,或更精确的重叠区域计算)。
代码
# import map files
NA_map <- readOGR(dsn = "./National_Constituency_Boundary", layer = "National_Constituency_Boundary")
PA_map <- readOGR(dsn = "./Provincial_Constituency_Boundary", layer = "Provincial_Constituency_Boundary")
# Both are now SpatialPolygonsDataFrame objects of 273 and 577 elements, respectively.
# If relevant, I used spdpylr to tweak some of data attribute names (for use later when joining to electoral dataframes):
NA_map <- NA_map %>%
rename(constituency_number = NA_Cons,
district_name = District,
province = Province)
PA_map <- PA_map %>%
rename(province = PROVINCE,
district_name = DISTRICT,
constituency_number = PA)
# calculate intersections, take one
Results <- gIntersects(NA_map, PA_map, byid = TRUE)
# this creates a large matrix of 157,521 elements
rownames(Results) <- NA_map@data$constituency_number
colnames(Results) <- PA_map@data$constituency_number
但是,尝试添加rowname / colname标签会给出错误消息:
Error in dimnames(x) <- dn :
length of 'dimnames' [1] not equal to array extent
如果没有rowname / colname标签,我无法读取叠加矩阵,也不能确定如何过滤它们,以便生成一个只有TRUE交叉点的列表,这些交叉点有助于制作NA-PA密钥。
我还尝试复制另外两个提出的解决方案来计算确切的重叠区域:
# calculate intersections, take two
pi <- intersect(NA_map, PA_map)
# this generates a SpatialPolygons object with 273 elements
areas <- data.frame(area=sapply(pi@polygons, FUN = function(x) {slot(x, 'area')}))
# this calculates the area of intersection but has no other variables
row.names(areas) <- sapply(pi@polygons, FUN=function(x) {slot(x, 'ID')})
这会生成错误消息:
Error in `row.names<-.data.frame`(`*tmp*`, value = c("2", "1", "4", "5", :
duplicate 'row.names' are not allowed
In addition: Warning message:
non-unique value when setting 'row.names': ‘1’
因此,当我尝试使用
将区域附加到属性信息时attArrea <- spCbind(pi, areas)
我收到错误消息
Error in spCbind(pi, areas) : row names not identical
尝试第三种方法:
# calculate intersections, take three
pi <- st_intersection(NA_map, PA_map)
生成错误消息:
Error in UseMethod("st_intersection") :
no applicable method for 'st_intersection' applied to an object of class "c('SpatialPolygonsDataFrame', 'SpatialPolygons', 'Spatial', 'SpatialPolygonsNULL', 'SpatialVector')"
我知道我的SPDF地图不能用于第三种方法,但是从描述中不清楚转换它并尝试这种方法需要哪些步骤。
求助的请求
任何有关使用这些方法所需的修正的建议,或指向其他一些方法的指示,都将不胜感激。谢谢!
答案 0 :(得分:1)
以下是一些示例数据
library(raster)
p <- shapefile(system.file("external/lux.shp", package="raster"))
p1 <- aggregate(p, by="NAME_1")
p2 <- p[, 'NAME_2']
所以我们有p1表示区域,而p2表示低级别。
现在我们可以做到
x <- intersect(p1, p2)
# or x <- union(p1, p2)
data.frame(x)
哪个应该(并且是)与原始
相同data.frame(p)[, c('NAME_1', 'NAME_2')]
要获取多边形的区域,可以执行
x$area <- area(x) / 1000000 # divide to get km2
由于边界略有变化,可能会有许多“条子”,非常小的多边形。这对你来说可能无关紧要。
但另一种方法可能是通过质心匹配:
y <- p2
e <- extract(p1, coordinates(p2))
y$NAME_1 <- e$NAME_1
data.frame(y)
答案 1 :(得分:0)
您的代码不是自包含的,因此我没有尝试复制您报告的错误。
但是,使用sf
软件包(用于在不久的将来取代rgeos
,rgdal
和sp
非常简单,获取所需的“密钥” )。见这里:
library(sf)
# Download shapefiles
national.url <- 'https://data.humdata.org/dataset/5d48a142-1f92-4a65-8ee5-5d22eb85f60f/resource/d85318cb-dcc0-4a59-a0c7-cf0b7123a5fd/download/national-constituency-boundary.zip'
provincial.url <- 'https://data.humdata.org/dataset/137532ad-f4a9-471e-8b5f-d1323df42991/resource/c84c93d7-7730-4b97-8382-4a783932d126/download/provincial-constituency-boundary.zip'
download.file(national.url, destfile = file.path(tempdir(), 'national.zip'))
download.file(provincial.url, destfile = file.path(tempdir(), 'provincial.zip'))
# Unzip shapefiles
unzip(file.path(tempdir(), 'national.zip'), exdir = file.path(tempdir(), 'national'))
unzip(file.path(tempdir(), 'provincial.zip'), exdir = file.path(tempdir(), 'provincial'))
# Read map files
NA_map <- st_read(dsn = file.path(tempdir(), 'national'), layer = "National_Constituency_Boundary")
PA_map <- st_read(dsn = file.path(tempdir(), 'provincial'), layer = "Provincial_Constituency_Boundary")
# Get sparse list representation of intersections
intrs.sgpb <- st_intersects(NA_map, PA_map)
length(intrs.sgpb) # One list element per national constituency
# [1] 273
print(intrs.sgpb[[1]]) # Indices of provnicial constituencies intersecting with first national constituency
# [1] 506 522 554 555 556
print(PA_map$PROVINCE[intrs.sgpb[[1]]])[1] # Name of first province intersecting with first national constituency
# [1] KHYBER PAKHTUNKHWA