Làm thế nào để đa giác không gian% trên% đa giác hoạt động khi tổng hợp các giá trị trong r?


12

Tôi đang làm việc trong một dự án dịch tễ học môi trường nơi tôi có phơi nhiễm điểm (~ 2.000 hoạt động của lợn công nghiệp - IHOs). Những IHOs phun trên cánh đồng gần đó, nhưng các giọt phân nước và khứu giác có thể đi dặm. Vì vậy, các mức phơi nhiễm này nhận được bộ đệm 3mi và tôi muốn biết số lượng phơi nhiễm IHO (với nhiều loại khác nhau - tổng số lượng phân, số lượng lợn, bất cứ thứ gì, đơn giản nhất, chỉ là số lượng bộ đệm phơi nhiễm chồng chéo) trên mỗi khối điều tra NC (~ 200.000). Các khối điều tra dân số loại trừ (màu xanh) là (1) bất cứ thứ gì trong 5 thành phố đông dân nhất và (2) các quận không giáp với quận có IHO trong đó (lưu ý: được thực hiện với chức năng gRelate và mã DE-9IM - rất lắt léo!). Xem hình ảnh dưới đây cho một hình ảnh

nhập mô tả hình ảnh ở đây

Bước cuối cùng là tổng hợp các đại diện tiếp xúc được đệm cho mọi khối điều tra dân số. Đây là nơi tôi đang bối rối.

Cho đến nay, tôi đã có thời gian tốt với các hàm% trên% trong gói sp, nhưng hiểu từ họa tiết trên rằng poly-poly và poly-line over được thực hiện trong rgeos. Các họa tiết chỉ bao gồm poly-line và poly tự tham chiếu, không bao gồm tổng hợp, vì vậy tôi hơi bối rối về các tùy chọn của mình cho poly-poly với tổng hợp chức năng, như tổng hoặc trung bình.

Đối với trường hợp thử nghiệm, hãy xem xét đoạn trích dưới đây, hơi dài dòng làm việc với tệp biên giới quốc gia trên thế giới. Điều này sẽ có thể được sao chép và chạy như vậy, vì tôi đang sử dụng một hạt giống ngẫu nhiên cho các điểm và vì tôi đang tải xuống và giải nén tệp thế giới trong mã.

Đầu tiên, chúng ta tạo 100 điểm, sau đó sử dụng hàm over với đối số fn để thêm phần tử vào khung dữ liệu. Có rất nhiều điểm ở đây, nhưng hãy xem Úc: 3 điểm, số 3 là nhãn hiệu. Càng xa càng tốt.

nhập mô tả hình ảnh ở đây

Bây giờ chúng ta biến đổi hình học để chúng ta có thể tạo bộ đệm, biến đổi trở lại và ánh xạ các bộ đệm đó. . mặc dù để có được điều đó với chức năng hơn. Xem mớ hỗn độn của tôi trong một dòng mã cuối cùng.

EDIT: Lưu ý rằng một người bình luận về r-sis-Geo đã đề cập đến hàm tổng hợp - cũng được tham chiếu trong câu hỏi trao đổi ngăn xếp 63577 - vì vậy một công việc xung quanh / dòng chảy có thể thông qua chức năng đó, nhưng tôi không hiểu tại sao tôi cần phải đi để tổng hợp cho polypoly khi dường như có chức năng đó cho các đối tượng không gian khác.

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?

Đánh giá cao chuyển hướng - tôi có nên xóa từ đây và đăng lại ở đó không? Động thái nào là tốt nhất? Cảm ơn.
Mike Dolan Fliss

Câu trả lời:


5

Cảm ơn câu hỏi rõ ràng và ví dụ tái sản xuất.

Sự hiểu biết của bạn là chính xác và điều này đã khắc phục một lỗi trong rgeos :: over, đã được sửa một tháng trước nhưng chưa biến nó thành bản phát hành CRAN. Sau đây là cách giải quyết nếu bạn chỉ quan tâm đến số lượng giao lộ:

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

Tôi đang sử dụng NROWở đây thay vì lengthđể nó hoạt động với các rgeos sai (0,3-8, từ CRAN) cũng như đã sửa (0,3-10, từ r-forge). Đề xuất sử dụng trước đó

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

cũng đếm số lượng giao lộ, nhưng chỉ với phiên bản rgeos cố định được cài đặt. Ưu điểm của nó, bên cạnh một tên trực quan hơn, là nó trực tiếp trả về một Spatialđối tượng, với hình dạng của world.map.

Để làm cho rgeos 0,3-8 hoạt động, thêm

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

vào kịch bản của bạn, trước khi bạn sử dụng over.


Rất hữu ích, cảm ơn bạn. Tôi đặc biệt muốn kỷ niệm việc bạn cung cấp một giải pháp hoạt động trước và sau sửa chữa. Bạn có phiền khi giải thích về: (1) Lỗi gì mà tôi đang gặp ở đây-rgeos :: over đang trả về một địa lý đa giác không gian, không phải là khung dữ liệu poly không gian? Không có một số chức năng chỉ trả về khung dữ liệu ...? (2) Làm thế nào điều này thường được cho là làm việc với tổng hợp và hơn? Tôi hơi bối rối về sự khác biệt dự định và trường hợp sử dụng của họ. Thực sự đánh giá cao cân nặng của bạn, cảm ơn bạn. Và sidenote: bất kỳ đề xuất để hiểu chu kỳ phát hành CRAN?
Mike Dolan Fliss

Ngoài ra, như câu hỏi ban đầu: Tôi cần đếm số lần phơi sáng, nhưng tôi cũng thực sự cần phải tính tổng chúng - những thứ như số lượng lợn hơi trong mỗi lần tiếp xúc. Đếm chồng chéo là một sự khởi đầu ... nhưng có vẻ như giải pháp tôi cần là kéo vào các rgeos mới nhất, đúng không? Không có cách nào để thực hiện tập hợp chức năng đó (không chỉ đếm) mà không có nó?
Mike Dolan Fliss

(1) rgeos :: over cho chữ ký SpatialPolygons,SpatialPolygonsDataFramesẽ trả về a data.frame, nhưng trả về một vectơ chỉ mục giống hệt như khi ySpatialPolygons. sp::aggregatethực hiện những gì bạn làm với hơn một cách thân thiện hơn, trả lại Spatialđối tượng thay vì data.frame. Các gói CRAN được duy trì bởi các tình nguyện viên.
Edzer Pebesma

OK, cảm ơn Edzer. Nghe có vẻ như tổng hợp dựa trên rgeos, vì vậy để có được chức năng này trước chu kỳ phát hành CRAN (khi đó là), tôi sẽ cần tìm hiểu cách tải xuống các rgeos mới nhất và xử lý nó. Cảm ơn bạn. Và cảm ơn cho tất cả các công việc của bạn trên gói !!
Mike Dolan Fliss

Ngoài ra, Edzer, cảm ơn rất nhiều vì đã ghi chú trên R-sis-Geo. Không chắc chắn nơi tốt hơn để đăng bài, vì vậy tôi rất vui vì chủ đề bây giờ chỉ ở đây.
Mike Dolan Fliss

1

Tôi đã tạo ra một trình thay thế quá nhanh (và được mã hóa kém) trong khi đó tạo ra khung dữ liệu mà tôi cần, vì câu hỏi của tôi không được trả lời bằng giải pháp chỉ đếm ở trên hoặc "giải quyết các rgeos mới", mà tôi Tôi không đủ giỏi để hiểu cách làm.

Hàm này rõ ràng (1) không đầy đủ (chú ý cách tôi bỏ qua đối số fn) và (2) không hiệu quả, vì tôi đến với nó mà không có thao tác mảng mạnh mẽ của R / sapply ... (rõ ràng tôi đến từ các ngôn ngữ khác mà không có sức mạnh đó) nhưng thành thật mà nói, tôi vẫn bối rối về cấu trúc của hàm over trả về (danh sách các danh sách ...? và danh sách trống nếu NA?). Đối với những gì đáng giá (chỉnh sửa được chào đón), chức năng này thực hiện công việc tôi cần thực hiện, thành công và bắt chước hành động của các chức năng khác trên các chức năng.

Chỉnh sửa chào mừng:

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
Tôi đã thêm một giải pháp thay thế để có được rgeos 0,3-8, theo câu trả lời của tôi.
Edzer Pebesma
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.