R cinsinden değerler toplanırken% poligon üzerinden% uzamsal poligon nasıl çalışır?


12

Nokta maruziyetlerimin olduğu bir çevresel epidemiyoloji projesi üzerinde çalışıyorum (~ 2.000 endüstriyel domuz operasyonu - IHO). Bu IHO'lar yakındaki tarlalara püskürtülür, ancak dışkı su damlacıkları ve kokusu kilometrelerce yol alabilir. Yani bu nokta maruziyetleri 3mi tamponları alıyor ve NC sayım blokları başına IHO maruziyetlerinin sayısını (çeşitli türlerde - gübre miktarı, domuz sayısı, her neyse; en basit, sadece üst üste binen maruz kalma tamponlarının sayısı) bilmek istiyorum. (~ 200,000). Hariç tutma sayımı blokları (mavi), (1) en kalabalık 5 şehirdeki herhangi bir şey ve (2) bir ilçeyi IHO ile sınırlamayan ilçelerdir (not: gRelate işlevi ve DE-9IM kodlarıyla yapılmıştır - çok kaygan!). Görsel için aşağıdaki resme bakın

resim açıklamasını buraya girin

Son adım, her sayım bloğuna tamponlu pozlama gösterimini toplamaktır. İşte burada güldüm.

Şimdiye kadar sp paketindeki% over% fonksiyonları ile iyi zaman geçirdim, ancak poli-poli ve poli-line üzerinden rgeos uygulanan aşırı skeç anlıyorum. Vinyet sadece çizgi-poli ve kendinden referanslı poli'yi kapsar ve toplama ile değil, bu yüzden seçeneklerimin toplam veya ortalama gibi fonksiyon toplama ile poli-poli için ne olduğu konusunda biraz kafam karıştı.

Bir test durumu için, dünya ülke sınırları dosyasıyla çalışan aşağıdaki biraz ayrıntılı pasajı göz önünde bulundurun. Puanlar için rastgele bir tohum kullandığımdan ve dünya dosyasını kodda indirip açtığımdan beri bu kopyalanmalı ve olduğu gibi çalıştırılmalıdır.

İlk olarak, 100 nokta oluştururuz, ardından öğeyi veri çerçevesine eklemek için over işlevini fn argümanıyla kullanırız. Burada çok puan var, ama Avustralya'ya bir bakın: 3 puan, etiket olarak 3 numara. Çok uzak çok iyi.

resim açıklamasını buraya girin

Şimdi geometrileri dönüştürüyoruz, böylece tampon oluşturabilir, geri dönüştürebilir ve bu tamponları eşleyebiliriz. (Önceki haritaya dahil, iki bağlantıyla sınırlı olduğum için.) Her ülkede kaç tamponun üst üste geldiğini bilmek istiyoruz - Avustralya'nın durumunda, göze göre, bu 4'tür. Hayatım boyunca neler olduğunu anlayamıyorum over fonksiyonu ile almak için olsa. Kodun son satırlarındaki girişimimi karıştırıyorum.

DÜZENLEME: r-sis-geo üzerinde yorum yapan bir yığın işlevi - aynı zamanda yığın değişim sorusu 63577 başvurulan - bahsettiğini bu yüzden etrafında / akış bir çalışma bu işlevi aracılığıyla olabilir, ama neden gitmek gerekir anlayamıyorum diğer uzamsal nesneler için bu işlevselliğe sahip gibi gözüktüğünde polipol için bir araya gelmek.

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?

Yönlendirmeyi takdir edin - buradan silmeli ve orada yeniden yayınlamalıyım? En iyi hamle nedir? Teşekkürler.
Mike Dolan Fliss

Yanıtlar:


5

Açık soru ve tekrarlanabilir örnek için teşekkürler.

Anlayışınız doğrudur ve bu bir ay önce düzeltilmiş ancak henüz bir CRAN sürümüne girmemiş olan rgeos :: over'daki bir hataya dayanmaktadır . Yalnızca kavşakların sayısıyla ilgileniyorsanız, aşağıdakileri bulabilirsiniz:

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

Ben kullanıyorum NROWyerine burada length(r-demirhaneye gelen, 0,3-10) yanı sıra düzeltmiyor (CRAN gelen 0,3-8) yanlış rgeos ile çalışır, böylece. Daha erken kullanma önerisi

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

aynı zamanda yalnızca sabit rgeos sürümü kurulu olan kavşak sayısını da sayar. Avantajı, daha sezgisel bir ismin yanı sıra, bir Spatialnesneyi, geometrisiyle doğrudan döndürmesidir world.map.

Rgeos 0.3-8'i çalıştırmak için

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

kullanmadan önce betiğinize ekleyin over.


Çok faydalı, teşekkürler. Özellikle düzeltme öncesi ve sonrası çalışan bir çözüm önerisini kutlamak istiyorum. (1) Burada vurduğum hata nedir-rgeos :: over uzamsal bir poli veri çerçevesi değil, uzamsal bir poligon coğrafyası döndürüyor mu? Bazı işlevler sadece veri çerçeveleri döndürmüyor mu? (2) Bunun genellikle agrega ve üzeri ile nasıl çalışması gerekiyor? Amaçlanan farklılıkları ve kullanım durumları konusunda biraz kafam karıştı. Tartımınızı gerçekten takdir ediyorum, teşekkür ederim. Ve sidenote: CRAN yayın döngüsünü anlamak için herhangi bir öneriniz var mı?
Mike Dolan Fliss

Ayrıca, asıl soruya gelince: Pozlama sayısını saymam gerekiyor, ama aynı zamanda onları toplamam da gerekiyor - her pozlamadaki domuz sayısı gibi şeyler. Çakışmaları saymak bir başlangıç ​​... ama ihtiyacım olan çözüm en yeni rgeoları çekmek gibi görünüyor, değil mi? Bu fonksiyonel toplama (sadece sayma değil) olmadan yapmanın bir yolu yok mu?
Mike Dolan Fliss

(1) rgeos :: üzerine imza için SpatialPolygons,SpatialPolygonsDataFramebir dönmelidir data.frame, ama ne zaman özdeş bir dizin vektörü döndüren yolurdu SpatialPolygons. sp::aggregateile yaptığınız işi daha kullanıcı dostu bir şekilde yapar, Spatialyerine nesneyi döndürür data.frame. CRAN paketleri gönüllüler tarafından yapılmaktadır.
Edzer Pebesma

Tamam, teşekkürler Edzer. Agrega rgeo'lara güveniyor gibi görünüyor, bu nedenle bu işlevselliği CRAN yayın döngüsünün önüne getirmek için (ne zaman olursa olsun), en yeni rgeo'ları nasıl indireceğimi ve bunun nasıl çözüleceğini öğrenmem gerekecek. Teşekkür ederim. Ve paket üzerindeki tüm çalışmalarınız için teşekkürler !!
Mike Dolan Fliss

Ayrıca Edzer, R-sis-geo'daki not için çok teşekkürler. Göndermek için daha iyi bir yer nerede olduğundan emin değildi, bu yüzden şimdi iş parçacığı burada işaret sevindim.
Mike Dolan Fliss

1

Bu arada, ihtiyacım olan veri çerçevesini oluşturan hızlı (ve kötü kodlanmış) bir aşırı ikameci çırptım, çünkü sorum yukarıdaki sadece sayma çözümü veya "yeni rgeolar üzerinde çalışıyorum" nasıl yapılacağını anlayacak kadar yetenekli değilim.

Bu fonksiyon açıkça (1) eksik (fn argümanını nasıl görmezden geldiğime dikkat edin) ve (2) verimsiz, çünkü R'nin güçlü dizi manipülasyonları / uygulaması olmadan geliyorum ... (açıkça başka dillerden geliyorum dürüst olmak gerekirse, yine de, over fonksiyonunun yapısının ne döndürdüğünü karıştırıyorum (liste listesi ...? Ve NA? ise boş listeler?). Değer için (düzenlemeler hoş geldiniz), bu işlev ihtiyacım olan işi başarılı bir şekilde yapar ve diğer işlevlerin üzerindeki eylemi taklit eder.

Düzenlemeler hoş geldiniz:

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
Cevabımı 0.3-8 rgeos sabitlemek için bir alternatif ekledim.
Edzer Pebesma
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.