รูปหลายเหลี่ยมเชิงพื้นที่% over% รูปหลายเหลี่ยมทำงานอย่างไรเมื่อรวมค่าใน r


12

ฉันกำลังทำงานในโครงการระบาดวิทยาด้านสิ่งแวดล้อมที่ฉันมีจุดรับสัมผัส (~ 2,000 HHO - IHOs) IHO เหล่านี้ฉีดพ่นในบริเวณใกล้เคียง แต่หยดน้ำและกลิ่นอุจจาระสามารถเดินทางได้หลายไมล์ ดังนั้นการเปิดเผยจุดเหล่านี้จะได้รับบัฟเฟอร์ 3mi และฉันต้องการทราบจำนวนการเปิดรับ IHO (ชนิดต่าง ๆ - ผลรวมของจำนวนมูล, จำนวนหมู, อะไรก็ตามที่ง่ายที่สุดเพียงจำนวนบัฟเฟอร์การสัมผัสซ้อนทับ) ต่อบล็อกสำรวจ NC (~ 200,000) บล็อกการสำรวจสำมะโนประชากร (สีฟ้า) คืออะไร (1) ในเมืองที่มีประชากรมากที่สุด 5 อันดับแรกและ (2) มณฑลที่ไม่ติดกับเขตที่มี IHO อยู่ในนั้น (หมายเหตุ: ทำด้วยฟังก์ชัน gRelate และรหัส DE-9IM - เนียนมาก!) ดูภาพด้านล่างสำหรับภาพ

ป้อนคำอธิบายรูปภาพที่นี่

ขั้นตอนสุดท้ายคือการรวมการแสดงแสงที่บัฟเฟอร์เข้ากับบล็อกการสำรวจสำมะโน ที่นี่ฉันอยู่นิ่งงัน

ฉันมีช่วงเวลาที่ดีกับฟังก์ชั่น% over% ในแพคเกจ sp จนถึงตอนนี้ แต่เข้าใจจากบทความสั้น ๆ ที่มีการใช้โพลีโพลีและโพลีไลน์มากกว่าในเรจ บทความสั้นครอบคลุมเฉพาะไลน์ - โพลีและการอ้างอิงตนเองและไม่ใช่การรวมดังนั้นฉันค่อนข้างสับสนเกี่ยวกับตัวเลือกของฉันสำหรับโพลี - โพลีที่มีการรวมฟังก์ชันเช่นผลรวมหรือค่าเฉลี่ย

สำหรับกรณีทดสอบให้พิจารณาข้อมูลด้านล่างนี้เป็นข้อมูลโค้ดที่ค่อนข้างละเอียดซึ่งทำงานกับไฟล์เส้นขอบประเทศโลก สิ่งนี้ควรจะสามารถคัดลอกและเรียกใช้ตามที่เป็นอยู่เนื่องจากฉันใช้เมล็ดสุ่มสำหรับจุดและเนื่องจากฉันกำลังดาวน์โหลดและคลายซิปไฟล์โลกในรหัส

อันดับแรกเราสร้าง 100 คะแนนจากนั้นใช้ฟังก์ชัน over กับอาร์กิวเมนต์ fn เพื่อเพิ่มองค์ประกอบใน data frame มีคะแนนมากมายที่นี่ แต่ดูที่ออสเตรเลีย: 3 คะแนน, อันดับ 3 เป็นป้ายกำกับ จนถึงตอนนี้ดีมาก

ป้อนคำอธิบายรูปภาพที่นี่

ตอนนี้เราเปลี่ยนรูปเรขาคณิตเพื่อให้เราสามารถสร้างบัฟเฟอร์แปลงกลับและจับคู่บัฟเฟอร์เหล่านั้น (รวมอยู่ในแผนที่ก่อนหน้านี้เนื่องจากฉัน จำกัด อยู่แค่สองลิงก์) เราต้องการทราบจำนวนบัฟเฟอร์ที่ทับซ้อนกันในแต่ละประเทศ - ในกรณีของออสเตรเลียด้วยตาเปล่านั่นคือ 4 ฉันไม่สามารถให้ชีวิตของฉันได้ว่าเกิดอะไรขึ้น แม้ว่าจะได้รับสิ่งนั้นด้วยฟังก์ชั่นโอเวอร์ ดูความยุ่งเหยิงของฉันในบรรทัดสุดท้ายของรหัส

แก้ไข: โปรดทราบว่าผู้แสดงความคิดเห็นใน r-sis-geo พูดถึงฟังก์ชั่นรวม - ยังอ้างถึงคำถามแลกเปลี่ยนสแต็ค 63577 - ดังนั้นการทำงาน / ไหลอาจจะผ่านฟังก์ชั่นนั้น แต่ฉันไม่เข้าใจว่าทำไมฉันต้องไป เพื่อรวมสำหรับโพลีโพลีเมื่อเวลาผ่านไปดูเหมือนว่าจะมีฟังก์ชั่นนั้นสำหรับวัตถุเชิงพื้นที่อื่น ๆ

require(maptools)
require(sp)
require(rgdal)
require(rgeos)

download.file("http://thematicmapping.org/downloads/TM_WORLD_BORDERS_SIMPL-0.3.zip", destfile="world.zip")
unzip("world.zip")
world.map = readOGR(dsn=".", "TM_WORLD_BORDERS_SIMPL-0.3", stringsAsFactors = F)
orig.world.map = world.map #hold the object, since I'm going to mess with it.

#Let's create 500 random lat/long points with a single value in the data frame: the number 1
set.seed(1)
n=100
lat.v = runif(n, -90, 90)
lon.v = runif(n, -180, 180)
coords.df = data.frame(lon.v, lat.v)
val.v = data.frame(rep(1,n))
names(val.v) = c("val")
names(coords.df) = c("lon", "lat")
points.spdf = SpatialPointsDataFrame(coords=coords.df, proj4string=CRS("+proj=longlat +datum=WGS84"), data=val.v)
points.spdf = spTransform(points.spdf, CRS(proj4string(world.map)))
plot(world.map, main="World map and points") #replot the map
plot(points.spdf, col="red", pch=20, cex=1, add=T) #...and add points.

#Let's use over with the point data
join.df = over(geometry(world.map), points.spdf,  fn=sum)
plot(world.map, main="World with sum of points, 750mi buffers") #Note - happens to be the count of points, but only b/c val=1.
plot(points.spdf, col="red", pch=20, cex=1, add=T) #...and add points.
world.map@data = data.frame(c(world.map@data, join.df))
#world.map@data = data.frame(c(world.map@data, over(world.map, points.spdf, fun="sum")))
invisible(text(getSpPPolygonsLabptSlots(world.map), labels=as.character(world.map$val), cex=1))
#Note I don't love making labels like above, and am open to better ways... plus I think it's deprecated/ing

#Now buffer...
pointbuff.spdf = gBuffer(spTransform(points.spdf, CRS("+init=EPSG:3358")), width=c(750*1609.344), byid=T)
pointbuff.spdf = spTransform(pointbuff.spdf, world.map@proj4string)
plot(pointbuff.spdf, col=NA, border="pink", add=T)



#Now over with the buffer (poly %over% poly).  How do I do this?
world.map = orig.world.map
join.df = data.frame(unname(over(geometry(world.map), pointbuff.spdf, fn=sum, returnList = F)) ) #Seems I need to unname this...?
names(join.df) = c("val")
world.map@data = data.frame(c(world.map@data, join.df)) #If I don't mess with the join.df, world.map's df is a mess..
plot(world.map, main="World map, points, buffers...and a mess of wrong counts") #replot the map
plot(points.spdf, col="red", pch=20, cex=1, add=T) #...and add points.
plot(pointbuff.spdf, col=NA, border="pink", add=T)
invisible(text(getSpPPolygonsLabptSlots(world.map), labels=as.character(world.map$val), cex=1)) 
#^ But if I do strip it of labels, it seems to be misassigning the results?
# Australia should now show 4 instead of 3.  I'm obviously super confused, probably about the structure of over poly-poly returns.  Help?

ชื่นชมการเปลี่ยนเส้นทาง - ฉันควรลบจากที่นี่และโพสต์ใหม่ตรงนั้นหรือไม่ ท่าไหนดีที่สุด? ขอบคุณ
Mike Dolan Fliss

คำตอบ:


5

ขอบคุณสำหรับคำถามที่ชัดเจนและตัวอย่างที่ทำซ้ำได้

ความเข้าใจของคุณถูกต้องและสิ่งนี้ทำให้เกิดข้อผิดพลาดใน rgeos :: มากกว่าซึ่งได้รับการแก้ไขเมื่อเดือนที่แล้ว แต่ยังไม่ได้ทำให้เป็นรุ่น CRAN ต่อไปนี้เป็นวิธีแก้ไขหากคุณสนใจเฉพาะจำนวนทางแยก:

world.map$val = sapply(over(geometry(world.map), pointbuff.spdf, returnList = TRUE), NROW)

ฉันใช้NROWที่นี่แทนlengthเพื่อที่จะทำงานกับ rgeos ที่ผิด (0.3-8, จาก CRAN) รวมถึงการแก้ไข (0.3-10 จาก r-forge) ข้อเสนอแนะก่อนหน้านี้ของการใช้

a = aggregate(pointbuff.spdf, world.map, sum)

ยังนับจำนวนของการแยก แต่จะติดตั้งเฉพาะรุ่น rgeos ประโยชน์ของมันนอกจากเป็นชื่อที่ง่ายขึ้นก็คือว่ามันโดยตรงส่งกลับวัตถุที่มีรูปทรงเรขาคณิตของSpatialworld.map

ในการทำให้ rgeos 0.3-8 ทำงานให้เพิ่ม

setMethod("over",
    signature(x = "SpatialPolygons", y = "SpatialPolygonsDataFrame"),
        rgeos:::overGeomGeomDF)

overสคริปต์ของคุณก่อนที่คุณใช้


มีประโยชน์มากขอบคุณ ฉันต้องการฉลองการเสนอโซลูชันที่ทำงานได้ทั้งก่อนและหลังการแก้ไข คุณจะช่วยอธิบายเพิ่มเติมเกี่ยวกับ: (1) สิ่งที่เป็นข้อบกพร่องที่ฉันกดปุ่มที่นี่ rgeos :: มากกว่าจะส่งกลับภูมิศาสตร์รูปหลายเหลี่ยมเชิงพื้นที่ไม่ใช่กรอบข้อมูลเชิงพื้นที่โพลี? ไม่ใช่ฟังก์ชั่นบางตัวที่ส่งคืนเฟรมข้อมูล ... ใช่ไหม (2) วิธีนี้โดยทั่วไปควรจะทำงานร่วมกับการรวมและมากกว่า? ฉันสับสนเล็กน้อยเกี่ยวกับความแตกต่างที่ตั้งใจไว้และใช้เคส ขอบคุณการชั่งน้ำหนักของคุณจริงๆขอบคุณ และ sidenote: คำแนะนำสำหรับการทำความเข้าใจรอบการปล่อย CRAN?
Mike Dolan Fliss

สำหรับคำถามเดิม: ฉันจำเป็นต้องนับจำนวนการเปิดเผย แต่ฉันก็ต้องสรุปพวกเขาด้วย - สิ่งต่าง ๆ เช่นจำนวนหมูในการเปิดรับแต่ละครั้ง การนับการทับซ้อนเป็นการเริ่มต้น ... แต่ดูเหมือนว่าโซลูชันที่ฉันต้องการคือการดึง rgeos ใหม่ล่าสุดใช่ไหม ไม่มีวิธีที่จะรวมการทำงานที่ (ไม่นับเพียง) โดยไม่ได้หรือไม่
Mike Dolan Fliss

(1) :: rgeos กว่าสำหรับลายเซ็นSpatialPolygons,SpatialPolygonsDataFrameควรกลับdata.frameแต่กลับเวกเตอร์ดัชนีเหมือนกับเมื่อจะได้รับy ไม่สิ่งที่คุณทำที่มีมากกว่าในทางที่ใช้งานง่ายขึ้น, คืนวัตถุแทน แพ็คเกจ CRAN ได้รับการดูแลโดยอาสาสมัคร SpatialPolygonssp::aggregateSpatialdata.frame
Edzer Pebesma

ตกลงขอบคุณ Edzer ดูเหมือนว่าการรวมจะขึ้นอยู่กับ rgeos ดังนั้นเพื่อให้สามารถใช้ฟังก์ชันนี้ได้ก่อนการเปิดตัว CRAN (เมื่อเป็นเช่นนั้น) ฉันจะต้องค้นหาวิธีการดาวน์โหลด rgeos ใหม่ล่าสุดและทำงานให้สำเร็จ ขอบคุณ. และขอบคุณสำหรับการทำงานทั้งหมดของคุณบนแพ็คเกจ !!
Mike Dolan Fliss

นอกจากนี้ Edzer ขอบคุณมากสำหรับบันทึกย่อของ R-sis-geo ไม่แน่ใจว่าตำแหน่งที่ดีกว่าในการโพสต์คืออะไรดังนั้นฉันดีใจที่เธรดตอนนี้ชี้ไปที่นี่
Mike Dolan Fliss

1

ฉันทำวิปเปอร์โอเวอร์เพลซที่รวดเร็ว (และมีโค้ดไม่ดี) ในระหว่างนี้ซึ่งสร้างเฟรมข้อมูลที่ฉันต้องการเนื่องจากคำถามของฉันยังไม่ได้รับคำตอบจากวิธีแก้ปัญหาการนับอย่างเดียวข้างต้นหรือ "แก้ปัญหา rgeos ใหม่" ซึ่งฉัน ยังไม่ชำนาญพอที่จะเข้าใจวิธีการทำ

ฟังก์ชั่นนี้ชัดเจน (1) ไม่สมบูรณ์ (สังเกตว่าฉันเพิกเฉยต่อข้อโต้แย้ง fn) และ (2) อย่างไม่มีประสิทธิภาพเนื่องจากฉันมาที่นี่โดยไม่ต้องใช้อาเรย์อาเรย์ที่มีประสิทธิภาพ / sapply ... (ชัดเจนว่าฉันมาจากภาษาอื่น พลังนั้น) แต่จริงๆแล้วฉันยังคงสับสนว่าโครงสร้างของฟังก์ชันโอเวอร์ส่งกลับอย่างไร (รายการของรายการ ... ? และรายการว่างถ้า NA?) สำหรับสิ่งที่คุ้มค่า (ยินดีต้อนรับการแก้ไข) ฟังก์ชั่นนี้ทำงานที่ฉันต้องทำสำเร็จและเลียนแบบการกระทำของฟังก์ชันอื่น ๆ

ยินดีต้อนรับการแก้ไข:

overhelper <- function(pol, pol.df, fn=sum, verbose=F){
   if(verbose) {cat("Building over geometry...\n"); t=Sys.time(); t}
   geolist = over(geometry(pol), pol.df, returnList = T)
   if(verbose) {cat("Geometry done. Aggregating df. \n"); Sys.time()-t;t=Sys.time();t;}
   results = data.frame(matrix(0,nrow=length(pol), ncol=ncol(pol.df)))
   names(results) = names(pol.df)
   end = length(geolist)

   for (i in 1:end){
     if(verbose) cat(i, "...")
     results[i,] = sapply(pol.df@data[unlist(geolist[i]),], fn)
   }
   if(verbose) cat("Aggregation done! (", Sys.time()-t, ") \n Returning result vector.")
   return (results)
}

1
ฉันเพิ่มทางเลือกอื่นเพื่อให้ได้ rgeos 0.3-8 แล้ว
Edzer Pebesma
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.