R中的SpatialPointsDataFrame属性和运算符


14

我已经SpatialPointsDataFrame使用spR中的包创建了一个类型为对象的对象。但是,对于@, $, . and []操作符以及何时使用它们来访问对象的不同属性,我感到困惑。这是我的示例代码:

library(sp)
library(rgdal)

#creating a SpatialPointsDataFrame with sample points in UTM
x <- c(15.2, 15.3, 15.4, 15.5, 15.7)
y <- c(50.4, 50.2, 50.3, 50.1, 50.4)
v1 <- c(1.0, 2.0, 3.0, 4.0, 5.0)
v2 <- c("a","b","b","c","a")
attributes <- as.data.frame(cbind(v1,v2))
xy <- cbind(x,y)
locationsDD <- SpatialPointsDataFrame(xy, attributes)
proj4string(locationsDD) <- CRS("+proj=longlat")
locations <- spTransform(locationsDD, CRS("+proj=utm +zone=33"))
plot(locations)

#using the different operators: WHEN TO USE @, $ or [] ?

#all these work!
property1 <- locations$v1
property2 <- locations@data$v1
property3 <- locations@data[,"v1"]
property4 <- locations@data["v1"]

#these also work
property5 <- locations@coords
property6 <- locations@bbox
property7 <- locations@coords[,2]

#these three work only in my special case
property8 <- locations@coords[,"y"]
property9 <- locations$x
property10 <- locations$y

#these don't work: $ operator is invalid for atomic vectors
property11 <- locations@coords$x
property12 <- locations@coords$y

何时可以使用@, $, []操作员,有人可以帮我吗?当我尝试阅读文档时,?SpatialPointsDataFrame我可以看到不同的属性,例如coords或,bbox但是我困惑@, $, []于使用哪个运算符来访问或修改它们。


1
因为这确实是关于R语法的问题,所以它并不特定于sp包或其对象。R随教程一起安装:在您的研究中开始。网络和印刷媒体提供了大量的学习资源R
whuber

Answers:


21

空间sp数据是S4类对象,由包含表示的空间要素类组件(例如,@ data包含属性,@ coords包含坐标对等)的插槽(使用@)组成。您可以使用slotNames()返回顶级插槽名称,但它不是递归的,并且不会为多边形类对象返回嵌套的插槽名称。每个插槽可以包含一个不同的对象类,在对其进行操作之前,应使用str()或class()进行检查。@data插槽始终是data.frame对象,@ coords是矩阵,而@polygons是具有附加插槽(labpt,area,hole,ringDir和coords)的列表对象。

它们的可用插槽和组织方式取决于所表示的要素类类型。SpatialPointsDataFrame对象是最基本的,而SpatialPolygonsDataFrame对象具有嵌套(如上所示)。代表每个多边形的嵌套结构必须考虑使用sapply之类的东西来对每个列表对象(多边形)进行操作。

这是一个使用sapply的示例,该方法通过依次遍历“多边形”,然后嵌套的“区域”插槽,来返回每个多边形的面积。

sapply(slot(sdat, 'polygons'), function(i) slot(i, 'area')) 

对于多边形对象,由于它们存储为每个多边形的列表,因此可以选择使用列表索引。以下是返回第一个多边形的示例(导致“ Polygon”类对象,而不是SpatialPolygonsDataFrame):

sdat@polygons[[1]]

在某些最新版本的sp中,开发人员已开始删除某些直接调用@data插槽的必要性。

例如,以前为@data编制索引:

sdat@data[sdat@data$att >= 0.5 ,]  

现在:

sdat[sdat$att >= 0.5 ,]

但是,如前所述,其他槽(例如,坐标,多边形等)不是这种情况。至于何时使用[]或$,仍然取决于操作类型。方括号“ []”可用于调用数据帧中的名称,但主要用于索引,而$具体用于调用数据帧中的列。对列名称进行“间接”调用的原因在于,开发人员添加了功能,以允许通过sp对象进行递归搜索。但是,为避免名称冲突(如您的示例;在数据框中具有x,y列将与@coord矩阵名称中的x,y名称发生冲突),存在一些内部一致性检查,这解释了为什么这仅在某些情况下有效实例。

一个方便的特性是您可以通过行索引来子集空间对象。在这里,我细分了前10个对象。

sub.sdat <- sdat[1:10,] 

或者,可以选择使用行索引向量的随机样本(n = 10)。

rs.sdat <- sdat[sample(1:nrow(sdat), 10),]

了解索引以及如何使用方括号是编写R代码中非常重要的事情。

编辑(2017年3月24日):请注意,遵循GeoJSON标准的简单要素(sf)类可能会成为R中空间对象的新标准。您可以在CRAN sf上阅读此类的详细说明网站R的简单功能


感谢您详细说明幕后发生的事情。看来,SpatialPointsDataFrame不仅@data列,而且@coords列都可以使用$运算符检索,而无需调用@coords插槽。因此sdat@coords$easting给出与相同的结果sdat$easting
jirikadlec2

好像您正在调用<at> data中的列。这与<at> coords插槽不同。您会注意到,如果调用colnames(sdat <at> coords),将返回矩阵列名称:“ coords.x1”,“ coords.x2”。不必在数据帧中保留坐标,并且由于它是重复的,因此不必占用大量内存。
Jeffrey Evans

不。我不是在<at>数据中调用该列。使用示例脚本中的SpatialPointsDataFrame colnames(locations@coords)返回,[1] "x" "y"colnames(locations@data)返回[1] "v1" "v2"。也许行为取决于用来创建SpatialPointsDataFrame的函数是什么?
jirikadlec2

其实我的第一句话有误。sdat@coords$easting不起作用,因为sdat @ coords是一个矩阵。但是sdat@coords[,"easting"]等于sdat@coords[,1]sdat$easting
jirikadlec2

需要说明的是,colnames()用于返回矩阵中的列名,而names()将返回NULL。虽然,name()和colnames()都可以在数据框对象(例如<at> data)上工作。从<at> coord矩阵检索数据的最佳方法是对它进行索引:sdat <at> coords [,1]或按列名sdat <at> coords [,“ coords.x1”]],但是正如您提到的,$不起作用,因为它是一个矩阵对象。
杰弗里·埃文斯

4

您应该尝试str(locations)澄清这一点。

例如,这些是正确的:

property2 <- locations@data$v1
property5 <- locations@coords
property6 <- locations@bbox
property7 <- locations@coords[,"x"]
property8 <- locations@coords[,2]

而这一次property1 <- locations$v1的作品,因为它引用的data.frame内的位置,@data


str(locations)给了我一些很好的提示。现在,我知道这@用于“类的插槽”。但是我仍然不明白为什么property9 <- locations$xnames(locations)不包含任何名为x
jirikadlec2的

1
创建SpatialPointDataFrame时,将x和y分配为坐标名称。如果查看locations @ coords,则可以看到带有坐标的矩阵。另外,如果尝试在@data中使用名称“ x”创建新列,则不能这样做,因为它已用作坐标名称。
Guillermo Olmedo 2014年

我仍然不太了解该SpatialPointsDataFrame对象用于通过$运算符访问坐标的“魔术” 。但是至少我现在更习惯使用它。我运行以下代码: colnames(locations@coords) <- c("easting","northing") 运行它后,locations$easting给我x坐标向量,locations$northing给我y坐标向量。
jirikadlec2 2014年

我认为以某种方式R将坐标的两列视为SpatialPointsDataFrame的数据框部分的另外两列。这就是为什么您可以在@data插槽内添加一个具有相同名称的列的原因
Guillermo Olmedo 2014年

1
似乎@coords矩阵中列的命名SpatialPointsDataFrame取决于SpatialPointsDataFrame对象的创建方式。方法一:coordinates(sdat) <- x ~ y将列重命名为"coords.x1", "coords.x2"。方法二:sdat <- SpatialPointsDataFrame(xy, attributes)xy矩阵中的原始列名保留下来。
jirikadlec2
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.