【问题标题】:Spatial inverse subset using square brackets in R在R中使用方括号的空间逆子集
【发布时间】:2020-09-17 20:42:31
【问题描述】:

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

和一个多边形 -> spatial_poly

我可以使用多边形内的所有点进行子集化

subset_within <- spatial_points[spatial_poly,]  which is nice and intuitive.

但是如果我想对多边形外的所有点进行子集化,我就不能使用

subset_ouside <- spatial_points[-spatial_poly,]

之前有人问过这个问题,答案是使用rgeos 包中的gDifference()。很好。

我的问题是,为什么 [ ] 用于内部选择,而不是相反?我不太明白错误信息

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.75,150.45),c(-30.75,-30.45,-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.

【问题讨论】:

  • 嗨。您能告诉我们您正在使用哪些软件包吗?如果您在包sp 中创建SpatialPointsDataFrame 并在sp 中创建Polygon,那么spatial_points[spatial_poly,] 只会引发错误。您能否将dput(spatial_points)dput(spatial_poly) 的结果添加到您的问题中?
  • 谢谢。实际上,你描述的确实有效。是的,使用 sp 但也使用 rgdal 和 raster。创建点文件是使用坐标()和我从外部源导入的形状文件。两者都使用 spTransform 进行转换。我对这两个文件都运行了 dput() 并且得到了一个非常长的 ascii 文件 - 你能告诉我我应该寻找什么吗?
  • 也许你可以展示一个最小的例子(即通过坐标制作一个多边形,并通过再现行为的坐标制作几个点)
  • @Allan Cameron 添加了示例。
  • 谢谢。请参阅我的答案以获得完整的解释。

标签: r spatial rgeo-shapefile


【解决方案1】:

当您在 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 类时,他必须编写基于传递给运算符@987654334 的操作数进行子集化的方法@。可以看源码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", pch = 16, add = TRUE)

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

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

当然,将- 运算符单独应用于SpatialPoints 对象并没有什么意义。 什么

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

我希望这能让事情更清楚。

【讨论】:

  • 非常感谢您的出色解释。我需要消化一些内容,但这一切都很有意义。我认为其他人也会发现这很有用。干杯!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-04-26
  • 1970-01-01
  • 2021-10-13
  • 1970-01-01
  • 1970-01-01
  • 2017-11-17
  • 2022-01-09
相关资源
最近更新 更多