Các thuộc tính và toán tử SpatialPointsDataFrame trong R


14

Tôi đã tạo một đối tượng kiểu SpatialPointsDataFramebằng cách sử dụng spgói trong R. Tuy nhiên, tôi bối rối về các @, $, . and []toán tử và khi nào sử dụng chúng để truy cập các thuộc tính khác nhau của đối tượng của tôi. Đây là mã mẫu của tôi:

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

Ai có thể giúp tôi, khi nào sử dụng các @, $, []toán tử? Khi tôi cố gắng đọc tài liệu, ?SpatialPointsDataFrametôi có thể thấy các thuộc tính khác nhau coords, bboxnhưng tôi bối rối không biết @, $, []sử dụng toán tử nào để truy cập chúng hoặc sửa đổi chúng.


1
Bởi vì đây thực sự là một câu hỏi về Rcú pháp, nó không đặc biệt cho spgói hoặc các đối tượng của nó. Rđược cài đặt với một hướng dẫn: bắt đầu ở đó trong nghiên cứu của bạn. Web và phương tiện truyền thông in ấn cung cấp nhiều tài nguyên bổ sung cho việc học R.
whuber

Câu trả lời:


21

Dữ liệu sp không gian là các đối tượng lớp S4 và được tạo thành từ các vị trí (được gọi là sử dụng @) có chứa các thành phần của lớp đối tượng không gian được biểu diễn (ví dụ: @data chứa các thuộc tính, @coords chứa các cặp tọa độ, v.v ...). Bạn có thể trả về tên vị trí cấp cao nhất bằng slotNames () nhưng nó không được đệ quy và sẽ không trả lại tên vị trí được lồng cho các đối tượng lớp đa giác. Mỗi vị trí có thể chứa một lớp đối tượng khác nhau và trước khi vận hành trên nó, nên được kiểm tra bằng str () hoặc class (). Vị trí @data luôn là một đối tượng data.frame và @coords là một ma trận trong khi @polygons là một đối tượng danh sách với các vị trí bổ sung (labpt, area, Hole, ringDir và coords).

Các vị trí và tổ chức có sẵn của chúng phụ thuộc vào loại lớp tính năng nào được thể hiện. Các đối tượng SpatialPointsDataFrame là cơ bản nhất, trong khi các đối tượng SpatialPolygonsDataFrame có lồng nhau (như đã thấy ở trên). Cấu trúc lồng nhau này, đại diện cho mỗi đa giác, phải được tính cho việc sử dụng một cái gì đó như sapply để hoạt động trên từng đối tượng danh sách (đa giác).

Dưới đây là một ví dụ sử dụng sapply để trả về diện tích cho mỗi đa giác bằng cách lặp qua "đa giác" sau đó, (các) vị trí "khu vực" lồng nhau.

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

Trong trường hợp các đối tượng đa giác, vì chúng được lưu trữ dưới dạng danh sách cho mỗi đa giác, bạn có thể thay thế sử dụng lập chỉ mục danh sách. Dưới đây là một ví dụ để trả về đa giác đầu tiên (dẫn đến một đối tượng lớp "Đa giác" chứ không phải SpatialPolygonsDataFrame):

sdat@polygons[[1]]

Trong các phiên bản gần đây hơn của sp, các nhà phát triển đã bắt đầu, trong một số trường hợp, loại bỏ sự cần thiết phải gọi trực tiếp vị trí @data.

Chẳng hạn, để lập chỉ mục @data bạn trước đây:

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

và bây giờ:

sdat[sdat$att >= 0.5 ,]

Tuy nhiên, như đã chỉ ra trước đây, đây không phải là trường hợp của các vị trí khác (ví dụ: tọa độ, đa giác, v.v ...). Cho đến khi sử dụng [] hoặc $, điều này vẫn phụ thuộc vào loại hoạt động. Chân đế "[]" có thể được sử dụng để gọi tên trong khung dữ liệu nhưng chủ yếu được sử dụng để lập chỉ mục trong khi $ được sử dụng cụ thể để gọi một cột trong khung dữ liệu. Lý do một cuộc gọi "gián tiếp" đến một tên cột hoạt động mà các nhà phát triển đã thêm chức năng để cho phép tìm kiếm đệ quy thông qua đối tượng sp. Tuy nhiên, để tránh xung đột tên (như trong ví dụ của bạn; có các cột x, y trong khung dữ liệu của bạn sẽ xung đột với tên x, y trong tên ma trận @coord), có một số kiểm tra tính nhất quán nội bộ cho thấy tại sao điều này chỉ hoạt động trong một số trường hợp.

Một đặc điểm tiện lợi là bạn có thể tập hợp một đối tượng không gian thông qua một chỉ mục hàng. Ở đây tôi đang tập hợp 10 đối tượng đầu tiên.

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

Hoặc, thay vào đó, một mẫu ngẫu nhiên (n = 10) sử dụng vectơ chỉ mục hàng.

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

Hiểu về lập chỉ mục và cách sử dụng dấu ngoặc là một điều rất quan trọng trong việc viết mã R.

Chỉnh sửa (24/03/2017): Xin lưu ý rằng lớp tính năng đơn giản (sf), theo tiêu chuẩn GeoJSON, có thể sẽ trở thành tiêu chuẩn mới cho các đối tượng không gian trong R. Bạn có thể đọc mô tả chi tiết về lớp này tại CRAN sf trang web đơn giản Nét đặc trưng cho R .


Cảm ơn đã giải thích chi tiết về những gì đang xảy ra đằng sau hậu trường. Dường như SpatialPointsDataFramekhông chỉ các cột @data mà cả các cột @coords có thể được truy xuất với $toán tử mà không cần phải gọi khe @coords. Vì vậy, sdat@coords$eastingcho kết quả tương tự như sdat$easting.
jirikadlec2

Có vẻ như bạn đang gọi một cột trong dữ liệu <at>. Điều này không giống với khe <at> coords. Bạn sẽ nhận thấy rằng nếu bạn gọi colnames (sdat <at> coords), bạn sẽ trả về tên cột ma trận: "coords.x1", "coords.x2". Không cần thiết phải giữ tọa độ trong khung dữ liệu và, vì nó được nhân đôi, một vòng eo của bộ nhớ.
Jeffrey Evans

Không. Tôi không gọi cột trong dữ liệu <at>. Sử dụng SpatialPointsDataFrame từ tập lệnh mẫu của tôi, colnames(locations@coords)trả về [1] "x" "y"nhưng colnames(locations@data)trả về [1] "v1" "v2". Có lẽ hành vi phụ thuộc vào chức năng nào đã được sử dụng để tạo SpatialPointsDataFrame?
jirikadlec2

Thật ra tôi có một lỗi trong bình luận đầu tiên của tôi. sdat@coords$eastingkhông hoạt động vì sdat @ coords là một ma trận. Nhưng sdat@coords[,"easting"]tương đương với sdat@coords[,1]sdat$easting.
jirikadlec2

Một cảnh báo, colnames () được sử dụng để trả về tên cột trong ma trận trong khi đó, tên () sẽ trả về NULL. Mặc dù, cả tên () và colnames () sẽ hoạt động trên một đối tượng khung dữ liệu, chẳng hạn như dữ liệu <at>. Cách tốt nhất để truy xuất dữ liệu từ ma trận tọa độ <at> là lập chỉ mục cho nó: sdat <at> coords [, 1] hoặc theo tên cột sdat <at> coords [, "coords.x1"] nhưng như bạn đã lưu ý $ không hoạt động vì nó là một đối tượng ma trận.
Jeffrey Evans

4

Bạn nên cố gắng str(locations)làm rõ điều này.

ví dụ, những cái này là chính xác:

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

Và cái này property1 <- locations$v1hoạt động, bởi vì nó đang tham chiếu data.frame bên trong location, @data


str(locations)đã cho tôi một số gợi ý tốt. Bây giờ tôi hiểu rằng nó @được sử dụng cho "slot of a class". Nhưng tôi vẫn không hiểu tại sao property9 <- locations$xhoạt động khi names(locations)không chứa bất kỳ cột nào có tênx
jirikadlec2

1
Khi bạn tạo SpatialPointDataFrame, bạn gán x và y làm tên tọa độ. Nếu bạn nhìn vào vị trí @ coords, bạn có thể thấy ma trận với tọa độ. Ngoài ra, nếu bạn cố gắng tạo một cột mới trong @data với tên "x", bạn không thể, vì nó đã được sử dụng làm tên tọa độ.
Guillermo Olmedo

Tôi vẫn không hoàn toàn hiểu được loại 'ma thuật' mà SpatialPointsDataFrameđối tượng sử dụng để truy cập tọa độ với $toán tử. Nhưng ít nhất tôi thấy thoải mái hơn khi sử dụng nó. Tôi đã chạy đoạn mã sau: colnames(locations@coords) <- c("easting","northing") Sau khi tôi chạy nó, locations$eastingđưa cho tôi vectơ tọa độ x và locations$northingđưa cho tôi vectơ tọa độ y.
jirikadlec2

Tôi nghĩ theo một cách nào đó, R coi hai cột cho tọa độ là hai cột nữa của phần khung dữ liệu của SpatialPointsDataFrame. Đó là lý do tại sao bạn có thể có một cột có cùng tên bên trong vị trí @data
Guillermo Olmedo

1
Có vẻ như việc đặt tên của các cột trong @coordsma trận của SpatialPointsDataFramephụ thuộc vào cách SpatialPointsDataFrametạo đối tượng. Phương pháp một: coordinates(sdat) <- x ~ ysẽ đặt lại tên cho các cột "coords.x1", "coords.x2". Phương pháp hai: sdat <- SpatialPointsDataFrame(xy, attributes)sẽ bảo toàn tên cột ban đầu khỏi xyma trận.
jirikadlec2
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.