问题描述
和一个多边形->空间多边形
我可以使用
来对多边形内的所有点进行子集化subset_within <- spatial_points[spatial_poly,] which is nice and intuitive.
但是,如果我想对多边形外的所有点进行子集化,则不能使用
subset_ouside <- spatial_points[-spatial_poly,]
之前曾有人问过这个问题,答案是使用gDifference()
包中的rgeos
。很好
我的问题是,为什么[]在内部进行选择而不是反向进行工作?我不太明白错误消息
h(simpleError(msg,call))中的错误:评估 参数'i'在为函数'['选择方法时:无效参数 一元运算符
很好奇。谢谢。
编辑
以下是从Subset spatial points with a polygon借来的示例
require(rgeos)
require(sp)
##create spdf
coords=expand.grid(seq(150,151,0.1),seq(-31,-30,0.1))
spdf=data.frame("lng"=coords[,1],"lat"=coords[,2])
coordinates(spdf) = ~lng+lat
proj4string(spdf)<- CRS("+init=epsg:4326")
plot(spdf)
##create poly
poly1 = Spatialpolygons(list(polygons(list(polygon(cbind(c(150.45,150.45,150.75,150.45),c(-30.75,-30.45,-30.75,-30.75)))),ID=1)))
proj4string(poly1)<- CRS("+init=epsg:4326")
##get points withing polygon
points_within <-spdf[poly1,] # this works
plot(spdf)
plot(poly1,add=T)
plot(points_within,col="blue",pch=16,add=T)
##get points outside polygon
points_outside <-spdf[-poly1,] # this does not work - why??
在这个简单的示例中,可以使用gDifference()
,在此示例中可以使用。但是,我的SpatialPointDataframe非常大,使用gDifference会使R崩溃。
解决方法
在R中执行df[2,1]
时,实际上是在调用函数。该函数为'['(df,1,2)
。只是解析器对您隐藏了它,这使您可以更自然地编写代码。
考虑一下,[
运算符会根据您使用的对象类型执行不同的操作,即使这些操作在概念上相似。返回数字矢量子集的实际代码与返回矩阵或列表的子集的代码不同。实际上,R中的某些对象对其调用[
函数是没有意义的,也没有实现。例如,如果您尝试使用函数名称调用它:
print[1]
#> Error in print[1] : object of type 'closure' is not subsettable
如果在R中使用各种不同的成员创建一个复杂的新类,则需要定义[
运算符的含义,并需要实现它。用SpatialPoints
类子集SpatialPolygon
类是什么意思? R无法独自知道这一点,因此,sp
包的创建者创建SpatialPolygons
类时,他不得不编写基于传递到的操作数进行子设置的方法。运算符[
。您可以看到源代码here。
如果追溯逻辑,您会发现在spdf[poly1,]
的情况下,子集是由其他空间函数决定的,归结为
which(!is.na(over(spdf,geometry(poly1))))
#> 39 40 41 50 51 52 61 62 63
#> 39 40 41 50 51 52 61 62 63
然后将这些数字子集用于实际多边形的子集,以返回仅由子集组成的新对象。这意味着我们可以通过类似的方式获得points_outside
:
points_within <- spdf[poly1,]
points_outside <- spdf[which(is.na(over(spdf,geometry(poly1))))]
plot(spdf)
plot(poly1,add = TRUE)
plot(points_within,col="blue",pch = 16,add = TRUE)
plot(points_outside,col="red",add = TRUE)
但是要回答您的主要问题,即spdf[-poly1,]
为什么不起作用,您必须意识到这实际上意味着'['(spdf,-poly1)
。要对此进行评估,首先必须评估-poly1
,但是如果尝试这样做,则会得到:
-poly1
#> Error in -poly1 : invalid argument to unary operator
当然,将-
运算符本身应用于SpatialPoints
对象实际上没有任何意义。从什么?
实际上,可以编写函数使其以这种方式工作,但是这将需要复杂的非标准评估。您可以在该GitHub页面上将其作为功能请求提交,但是我个人会很高兴使用上面的功能。
我希望这可以使事情变得更清楚。