คุณสมบัติและตัวดำเนินการ SpatialPointsDataFrame ใน R


14

ฉันได้สร้างวัตถุชนิดSpatialPointsDataFrameโดยใช้spแพคเกจใน R อย่างไรก็ตามฉันสับสนเกี่ยวกับตัว@, $, . 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

คำตอบ:


21

ข้อมูล spatial sp เป็นคลาสคลาส S4 และประกอบด้วยสล็อต (เรียกว่าใช้ @) ที่มีส่วนประกอบของคลาสคุณลักษณะเชิงพื้นที่ที่แสดง (เช่น @data มีแอตทริบิวต์ @coords มีคู่ประสานงาน ฯลฯ ... ) คุณสามารถส่งคืนชื่อสล็อตระดับบนสุดโดยใช้ slotNames () แต่ไม่เรียกซ้ำและจะไม่ส่งคืนชื่อสล็อตที่ซ้อนกันสำหรับวัตถุคลาสเหลี่ยม แต่ละสล็อตสามารถมีคลาสอ็อบเจ็กต์ที่แตกต่างกันและควรตรวจสอบก่อนใช้งานโดยใช้ str () หรือ class () สล็อต @ data เป็นวัตถุ data.frame เสมอและ @coords เป็นเมทริกซ์ในขณะที่ @polygons เป็นวัตถุรายการที่มีสล็อตเพิ่มเติม (labpt, พื้นที่, รู, ringDir และ coords)

สล็อตและการจัดระเบียบที่พร้อมใช้งานของพวกเขาจะขึ้นอยู่กับประเภทของคุณลักษณะคลาสที่จะถูกแสดง วัตถุ SpatialPointsDataFrame เป็นพื้นฐานที่สุดในขณะที่วัตถุ SpatialPolygonsDataFrame มีการซ้อน (ตามที่เห็นด้านบน) โครงสร้างที่ซ้อนกันนี้ซึ่งแสดงถึงรูปหลายเหลี่ยมแต่ละอันจะต้องนำมาใช้ในการใช้บางสิ่งบางอย่างเช่น sapply เพื่อใช้งานกับแต่ละรายการวัตถุ (รูปหลายเหลี่ยม)

นี่คือตัวอย่างที่ใช้ sapply เพื่อส่งคืนพื้นที่สำหรับรูปหลายเหลี่ยมแต่ละรูปด้วยการวนซ้ำผ่าน "รูปหลายเหลี่ยม" จากนั้นช่องที่ซ้อนกัน "พื้นที่"

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

ในกรณีของวัตถุรูปหลายเหลี่ยมเนื่องจากวัตถุเหล่านั้นถูกเก็บไว้เป็นรายการสำหรับรูปหลายเหลี่ยมแต่ละรูปคุณสามารถใช้การสร้างดัชนีรายการได้ นี่คือตัวอย่างที่จะคืนค่ารูปหลายเหลี่ยมแรก (ส่งผลให้วัตถุคลาส "รูปหลายเหลี่ยม" ไม่ใช่ SpatialPolygonsDataFrame):

sdat@polygons[[1]]

ในเวอร์ชันล่าสุดของ sp ผู้พัฒนาได้เริ่มต้นในบางกรณีเอาความจำเป็นในการเรียกใช้ @data slot โดยตรง

ตัวอย่างเช่นหากต้องการดัชนี @data คุณก่อนหน้านี้:

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

และตอนนี้:

sdat[sdat$att >= 0.5 ,]

อย่างไรก็ตามตามที่ระบุไว้ก่อนหน้านี่ไม่ใช่กรณีของช่องอื่น ๆ (เช่นพิกัดรูปหลายเหลี่ยม ฯลฯ ... ) เท่าที่จะใช้ [] หรือ $ นี้ยังขึ้นอยู่กับประเภทของการดำเนินการ วงเล็บ "[]" สามารถใช้เรียกชื่อใน dataframe ได้ แต่ส่วนใหญ่จะใช้สำหรับการทำดัชนีในขณะที่ $ ถูกใช้เพื่อเรียกคอลัมน์ใน dataframe โดยเฉพาะ สาเหตุที่การเรียก "ทางอ้อม" ไปยังชื่อคอลัมน์ทำงานได้โดยผู้พัฒนาได้เพิ่มฟังก์ชันการทำงานเพื่อให้สามารถค้นหาแบบเรียกซ้ำผ่านวัตถุ sp อย่างไรก็ตามเพื่อหลีกเลี่ยงความขัดแย้งของชื่อ (เช่นในตัวอย่างของคุณการที่มีคอลัมน์ x, y ใน dataframe ของคุณอาจขัดแย้งกับชื่อ x, y ในชื่อเมทริกซ์ @coord) มีการตรวจสอบความสอดคล้องภายในบางอย่างที่อธิบายว่าทำไม ตัวอย่าง.

คุณลักษณะที่สะดวกอย่างหนึ่งคือคุณสามารถเซ็ตย่อยวัตถุเชิงพื้นที่ผ่านดัชนีแถว ที่นี่ฉันกำลัง subsetting 10 วัตถุแรก

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

หรือมิฉะนั้นตัวอย่างสุ่ม (n = 10) โดยใช้เวกเตอร์ดัชนีแถว

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

การทำความเข้าใจกับการจัดทำดัชนีและวิธีใช้วงเล็บเป็นสิ่งสำคัญมากในการเขียนรหัส R

แก้ไข (03/24/2017): โปรดทราบว่าคลาสฟีเจอร์ (sf) ตามมาตรฐาน GeoJSON น่าจะกลายเป็นมาตรฐานใหม่สำหรับวัตถุอวกาศในอาร์คุณสามารถอ่านคำอธิบายโดยละเอียดของคลาสนี้ได้ที่ CRAN sf เว็บไซต์ง่ายคุณสมบัติสำหรับ R


ขอบคุณสำหรับคำอธิบายโดยละเอียดเกี่ยวกับสิ่งที่เกิดขึ้นเบื้องหลัง ปรากฏว่าSpatialPointsDataFrameไม่เพียง แต่คอลัมน์ @data แต่ยังสามารถดึงคอลัมน์ @coords ด้วยตัว$ดำเนินการโดยไม่จำเป็นต้องเรียกใช้ช่อง @coords ดังนั้นจะช่วยให้ผลเช่นเดียวกับsdat@coords$easting sdat$easting
jirikadlec2

ดูเหมือนว่าคุณกำลังเรียกคอลัมน์ในข้อมูล <at> สิ่งนี้ไม่เหมือนกับสล็อต <at> coords คุณจะสังเกตเห็นว่าถ้าคุณเรียกชื่อ colnames (sdat <at> coords) คุณจะกลับชื่อคอลัมน์ matrix: "coords.x1", "coords.x2" ไม่จำเป็นต้องเก็บพิกัดไว้ใน dataframe และเนื่องจากเป็นข้อมูลที่ซ้ำซ้อนซึ่งเป็นหน่วยความจำ
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

หนึ่ง caveat, colnames () ใช้ในการส่งกลับชื่อคอลัมน์ในเมทริกซ์ในขณะที่ชื่อ () จะกลับ NULL แม้ว่าทั้ง names () และ colnames () จะทำงานกับวัตถุ dataframe เช่น <at> data วิธีที่ดีที่สุดในการดึงข้อมูลจาก <at> coord matrix คือการจัดทำดัชนี: sdat <at> coords [, 1] หรือโดยชื่อคอลัมน์ sdat <at> coords [, "coords.x1"] แต่ตามที่คุณบันทึก $ ไม่ทำงานเพราะมันเป็นวัตถุเมทริกซ์
Jeffrey Evans

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)ให้คำแนะนำที่ดีแก่ฉัน ตอนนี้ฉันเข้าใจแล้วว่า@ใช้สำหรับ "slot of a class" แต่ฉันก็ยังไม่เข้าใจว่าทำไมproperty9 <- locations$xทำงานเมื่อnames(locations)ไม่มีคอลัมน์ชื่อx
jirikadlec2

1
เมื่อคุณสร้าง SpatialPointDataFrame คุณจะกำหนด x และ y เป็นชื่อพิกัด หากคุณดูที่ location @ coords คุณสามารถดูเมทริกซ์ด้วยพิกัด นอกจากนี้หากคุณพยายามสร้างคอลัมน์ใหม่ใน @data ด้วยชื่อ "x" คุณไม่สามารถทำได้เพราะมันใช้เป็นชื่อพิกัดแล้ว
Guillermo Olmedo

ฉันยังไม่เข้าใจว่า 'เวทย์มนตร์' ชนิดใดที่SpatialPointsDataFrameวัตถุใช้สำหรับการเข้าถึงพิกัดกับตัว$ดำเนินการ แต่อย่างน้อยฉันก็รู้สึกสบายใจที่จะใช้มันตอนนี้ ฉันเรียกใช้รหัสต่อไปนี้: colnames(locations@coords) <- c("easting","northing") หลังจากฉันเรียกใช้แล้วlocations$eastingให้เวกเตอร์พิกัด x และlocations$northingมอบเวกเตอร์พิกัด y ให้ฉัน
jirikadlec2

ฉันคิดว่า R จะพิจารณาสองคอลัมน์สำหรับพิกัดเป็นคอลัมน์อีกสองคอลัมน์ของส่วน dataframe ของ SpatialPointsDataFrame นั่นเป็นเหตุผลที่คุณสามารถมีคอลัมน์ที่มีชื่อเดียวกันอยู่ในช่อง @data ได้
Guillermo Olmedo

1
ดูเหมือนว่าการตั้งชื่อของคอลัมน์ใน@coordsเมทริกซ์ของSpatialPointsDataFrameจะขึ้นอยู่กับวิธีการSpatialPointsDataFrameสร้างวัตถุ วิธีที่หนึ่ง: coordinates(sdat) <- x ~ yจะ "coords.x1", "coords.x2"re-ชื่อคอลัมน์ที่จะ วิธีที่สอง: sdat <- SpatialPointsDataFrame(xy, attributes)จะรักษาชื่อคอลัมน์ดั้งเดิมจากxyเมทริกซ์
jirikadlec2
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.