我试图在循环中使用带有R的gIntersection函数执行多个多边形剪辑。我可以手动获取正确的剪辑并重新输入数据(因此我可以将生成的SpatialPolygons对象转换回SpatialPolygonsDataFrame对象)。我无法做到的是使用for()
或apply()
使其正常工作。
目前这不是一个问题。我有9个英语区域(伦敦),因此手动设置每个剪辑并不是一个巨大的挑战。但是,我想最终在LAD中剪辑LSOA,这实质上意味着设置> 400个剪辑。
所以,我的问题是,如何将手动剪辑转换为工作循环?
为了简单起见,让我们使用英语区域(n = 9)。对于9个地区中的每个地区,我都要剪掉这些县。以下代码加载适当的shapefile并将它们重新投影为British National Grid:
require(rgdal)
require(rgeos)
# English counties shapefile (~ 10MB zipped)
download.file(
"https://dl.dropboxusercontent.com/s/6o0mi28pjo1kh9k/england-counties.zip",
"ec", method = "wget")
unzip("ec")
ec <- readOGR("england-counties", "england_ct_2011")
proj4string(ec) <- CRS("+init=epsg:27700")
# English regions (~6MB zipped)
download.file(
"https://dl.dropboxusercontent.com/s/p69m0vk2fh4xe3o/england-regions-2011.zip",
"er", method = "wget")
unzip("er")
er <- readOGR("england-regions-2011", "England_gor_2011")
proj4string(er) <- CRS("+init=epsg:27700")
您应该留下两个对象er
(英语区域)和ec
(英语县)。两者都是SpatialPolygonsDataFrame对象。
选择第一个地区 - 英格兰东部E12000006
- 让我们剪切县并将结果重新转换为SpatialPolygonsDataFrame对象:
ee <- gIntersection(ec, er[er$CODE == "E12000006", ],
byid = T, drop_not_poly = T)
row.names(ee) <- as.character(gsub(" 0", "", row.names(ee)))
# gIntersection adds ' 0' to each row.name?
ee <- SpatialPolygonsDataFrame(ee, ec@data[row.names(ee), ])
ee
的情节证实了这一点:
正如您所看到的,这对于几个形状来说是一个很好的工作流程,但我真的想要遍历所有区域,最终还有更多的多边形。
我对apply()
循环不是很好,所以我到目前为止尝试的是一个for()
循环(我知道它比较慢,但仍然比键入更快一切都出来了!):
regions <- as.character(er$CODE) # length = 9 as expected
for(i in 1:length(regions)){
as.name(paste0(regions[i], "c")) <-
gIntersection(ec, er[er$CODE == regions[1], ], byid = T, drop_not_poly = T)
}
而不是预期的行为,我得到以下错误:
Error in as.name(paste0(regions[1], "c")) <- gIntersection(ec, er[er$CODE == :
could not find function "as.name<-"
我还尝试将对象名称包装在eval()
中,但出现以下错误:
Error in eval(as.name(paste0(regions[1], "c"))) <- gIntersection(ec, er[er$CODE == :
could not find function "eval<-"
我错过了什么?
除了gIntersection之外,我想尽可能重新创建一个SpatialPolygonsDataFrame对象。我已经尝试了以下代码,手动完成了一个gIntersection,但它再次没有工作:
for(i in 1:length(regions)){
row.names(as.name(paste0(regions[i], "c"))) <- as.character(gsub(" 0", "",
row.names(as.name(paste0(regions[i], "c")))))
}
我收到以下错误:
Error in `rownames<-`(x, value) :
attempt to set 'rownames' on an object with no dimensions
我也不确定如何增加" 0"
,因为每个新区域(" 1"
," 2"
等都会增加一个。)
同样,手动设置第一个示例我也无法执行最终的SpatialPolygonsDataFrame步骤:
for(i in 1:length(regions)){
as.name(regions[i]) <- SpatialPolygonsDataFrame(regions[i],
ec@data[row.names(regions[i], )])
}
为此,我收到以下错误:
Error in stopifnot(length(Sr@polygons) == nrow(data)) :
trying to get slot "polygons" from an object of a basic class ("character") with no
slots
以下相关的SO示例似乎没有帮助,或者至少我无法看到如何将它们应用于此示例:
感谢您花时间阅读本文。
答案 0 :(得分:1)
这有帮助吗?
ee <- lapply(regions, function(x)
gIntersection(ec, er[er$CODE == x, ], byid = TRUE, drop_not_poly = TRUE))
这将为您提供SpatialPolygonsDataFrame的列表,每个区域对应一个。您可以通过常规方式访问,例如
ee[[1]]
plot(ee[[1]]) # to plot the first region with counties
你的orignial代码应该使用sligh修改(见打击)。
res <- list()
for (i in 1:length(regions)) {
ee <- gIntersection(ec, er[er$CODE == regions[i], ],
byid = TRUE, drop_not_poly = TRUE)
row.names(ee) <- as.character(gsub(paste0(" ", i-1), "", row.names(ee)))
ee <- SpatialPolygonsDataFrame(ee, ec@data[row.names(ee), ])
res[[i]] <- ee
}
如果这样可以解决问题,那么问题是,ee
的行名称总是加1而你没有考虑到这一点。