R中使用方括号的空间逆子集

问题描述

我有一个空间点数据框->空间点

一个多边形->空间多边形

我可以使用

来对多边形内的所有点进行子集化
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)

enter image description here

但是要回答您的主要问题,即spdf[-poly1,]为什么不起作用,您必须意识到这实际上意味着'['(spdf,-poly1)。要对此进行评估,首先必须评估-poly1,但是如果尝试这样做,则会得到:

-poly1
#> Error in -poly1 : invalid argument to unary operator

当然,将-运算符本身应用于SpatialPoints对象实际上没有任何意义。从什么

中删除点

实际上,可以编写函数使其以这种方式工作,但是这将需要复杂的非标准评估。您可以在该GitHub页面上将其作为功能请求提交,但是我个人会很高兴使用上面的功能。

我希望这可以使事情变得更清楚。