Uzayda ve zamanda yakınlık


10

İlişkili bir zaman damgası ile bir hayvanın günlük lat-lon konumlarını temsil eden bazı nokta verilerim var.

STATIONARY = TRUE olan tüm noktaları tanımlamak istiyorum. Etrafında 100 km'lik bir tampon ek olarak (örneğin) 5 geçici olarak bitişik nokta ile çakışırsa, bir nokta sabit olarak nitelendirilir . Eğer 10. gün ilgi alanımsa, geçici olarak bitişik 5 günün bu noktanın 100 km'lik bir tamponu içinde olup olmadığını sormak istiyorum. 5,6,7,8 & 9 günleri; VEYA günler 11,12,13,14 & 15; VEYA 8,9,11,12,13 (vb.) Günleri tampon içinde, daha sonra SABİT = DOĞRU. Bununla birlikte, 5,7,9,11 & 13 günleri arabellek içindeyse, ancak aradaki alternatif (çift) günler değilse, STATIONARY = FALSE

Sanırım bir çeşit hareketli pencere tamponu çözümü sağlayacak, ama bunu nasıl uygulayacağımı bilmiyorum.

Hem ArcGIS hem de R'de başım bu problemi çözmeye çalışıyordum, ancak şu ana kadar beyin dalgalarım olmadı. Bu, bir çözüme en yakın olanıdır, ancak tam olarak uymuyor, sanmıyorum: Belirli bir tamponda ardışık noktaların tanımlanması

İşte veri yapıma yaklaşan bazı kukla veriler (gerçekte bazı yerlerde eksik olan günde iki kez (gece yarısı ve gece yarısı) yerim var - ancak daha sonra endişeleneceğim)

x<-seq(0,15,length.out=20)
y<-seq(10,-10,length.out=20)
t<-seq(as.POSIXct('2013-07-01'), length.out = 20, by = "days")
data<-data.frame(cbind(x,y,t=as.data.frame.POSIXct(t)))


            x           y          t
1   0.0000000  10.0000000 2013-07-01
2   0.7894737   8.9473684 2013-07-02
3   1.5789474   7.8947368 2013-07-03
4   2.3684211   6.8421053 2013-07-04
5   3.1578947   5.7894737 2013-07-05
6   3.9473684   4.7368421 2013-07-06
7   4.7368421   3.6842105 2013-07-07
... ...         ...       ...

1
Soru? 10 noktanın da arabellek içinde olduğu ve 1-3-4-12-13-20-21-22-29-30 arasında bir tarih ayrımına sahip olduğunuzu varsayarak (1. günden başlayarak) 1,2,3,4 & 12.
Hornbydd

Hayır, sadece 1-4. Günlerde ilgilenirim. Hayvan tampondan ayrılırsa, 12. günde (veya 6. günde) geri dönerse, o zaman bu durağan dönemi 'iptal eder' - yani hayvan 1-2-3-4-5. Günde tamponda olmalıdır. sayılacak tamponun merkezindeki nokta. Mantıklı olmak? Kendimden emin değilim ..
Tom Finch

1
Sadece kontrol etmek, eğer ilgi noktası 7. gün olsaydı, o zaman 7,8,9,10 & 11 gün için 100Km içinde düşen ilgilenen noktalar olurdu?
Hornbydd

8,9,10, 11 ve 12. günler 100km gidiyorsa, 7. nokta sabit bir nokta olarak seçilecektir. Veya günler 5,6,8,9,10. Bu nedenle, geçici olarak bitişik diğer 5 noktanın (önceki 5 gün, sonraki 5 gün veya her iki tarafın birkaç günü) arabellek içinde olması durumunda herhangi bir nokta seçilir. Hareketli pencerenin onu kavramsallaştırmanın en iyi yolu olduğunu düşünüyorum. Her 'odak' noktası için geçmişe / geleceğe 5 günden fazla herhangi bir nokta unutulabilir. Orijinal sorumu güncelleyebilirim, şimdi biraz daha anladım ...
Tom Finch

Verilerin formatı nedir? Örneğin, bir şekil dosyasında vektör noktası ve zamanı saklayan bir öznitelik tablosu olarak her zaman / konum var mı? Veya her zaman / konum farklı şekil dosyalarında ayrı olarak mı saklanıyor? Veriler coğrafi bir formatta değil, sadece bir Excel dosyasında mı? Bunu bilmek cevap vermemize yardımcı olur.

Yanıtlar:


12

Bunu basit parçalara ayıralım. Bu şekilde, tüm işler sadece yarım düzine satırda kolayca test edilen kodda gerçekleştirilir.

İlk olarak, mesafeleri hesaplamanız gerekecektir. Veriler coğrafi koordinatlarda olduğundan, küresel bir veri üzerindeki mesafeleri hesaplamak için bir işlev (Haversine formülü kullanılarak):

#
# Spherical distance.
# `x` and `y` are (long, lat) pairs *in radians*.
dist <- function(x, y, R=1) {
  d <- y - x
  a <- sin(d[2]/2)^2 + cos(x[2])*cos(y[2])*sin(d[1]/2)^2
  return (R * 2*atan2(sqrt(a), sqrt(1-a)))
}

İsterseniz bunu en sevdiğiniz uygulama ile değiştirin (elipsoidal datum kullanan bir uygulama gibi).

Daha sonra, her "temel nokta" (staionarite için kontrol ediliyor) ve geçici komşuları arasındaki mesafeleri hesaplamamız gerekecek. Bu sadece distmahalleye başvurma meselesi :

#
# Compute the distances between an array of locations and a base location `x`.
dist.array <- function(a, x, ...) apply(a, 1, function(y) dist(x, y, ...))

Üçüncüsü - bu anahtar fikirdir - durağan noktalar, mesafeleri yeterince küçük olan arka arkaya en az beş olan 11 noktanın mahallelerini tespit ederek bulunur. Mantıksal bir boole değerleri dizisindeki gerçek değerlerin en uzun dizisinin uzunluğunu belirleyerek bunu biraz daha genel olarak uygulayalım:

#
# Return the length of the longest sequence of true values in `x`.
max.subsequence <- function(x) max(diff(c(0, which(!x), length(x)+1)))

( Yanlış değerlerin konumlarını sırayla buluruz ve farklılıklarını hesaplarız: bunlar yanlış olmayan değerlerin alt dizileridir. Bu en büyük uzunluk döndürülür.)

Dördüncüsü, max.subsequencedurağan noktaları tespit etmek için başvuruyoruz .

#
# Determine whether a point `x` is "stationary" relative to a sequence of its
# neighbors `a`.  It is provided there is a sequence of at least `k`
# points in `a` within distance `radius` of `x`, where the earth's radius is
# set to `R`.
is.stationary <- function(x, a, k=floor(length(a)/2), radius=100, R=6378.137) 
  max.subsequence(dist.array(a, x, R) <= radius) >= k

Bunlar ihtiyacımız olan aletler.


Örnek olarak, birkaç durağan nokta kümesine sahip bazı ilginç veriler oluşturalım. Ekvator'un yakınında rastgele bir yürüyüş yapacağım.

set.seed(17)
n <- 67
theta <- 0:(n-1) / 50 - 1 + rnorm(n, sd=1/2)
rho <- rgamma(n, 2, scale=1/2) * (1 + cos(1:n / n * 6 * pi))
lon <- cumsum(cos(theta) * rho); lat <- cumsum(sin(theta) * rho)

Dizileri sırayla nokta cinsinden sıralar lonve latkoordinatları içerir n. İlk olarak radyana dönüştükten sonra araçlarımızı uygulamak basittir:

p <- cbind(lon, lat) * pi / 180 # Convert from degrees to radians
p.stationary <- sapply(1:n, function(i) 
  is.stationary(p[i,], p[max(1,i-5):min(n,i+5), ], k=5))

Argüman p[max(1,i-5):min(n,i+5), ]taban noktasından 5 zaman adımına veya 5 zaman adımına kadar ileriye baktığını söylüyor p[i,]. Dahil etme k=5, taban noktasının 100 km'sinde olan bir sırada 5 veya daha fazla bir sıra aradığını söylüyor. (100 km değeri varsayılan olarak ayarlandı, is.stationaryancak burada geçersiz kılabilirsiniz.)

Çıktı p.stationarydurağanlığı gösteren mantıklı bir vektördür: bizim için ne geldiğimize sahibiz. Ancak, prosedürü kontrol etmek için değer dizilerini incelemek yerine verileri ve bu sonuçları çizmek en iyisidir. Aşağıdaki grafikte rotayı ve puanları göstereceğim. Her onuncu nokta etiketlidir, böylece sabit kümeler içinde kaç kişinin çakışabileceğini tahmin edebilirsiniz. Sabit noktalar, onları vurgulamak için düz kırmızı renkte yeniden çizilir ve 100 km'lik tamponlarıyla çevrelenir.

şekil

plot(p, type="l", asp=1, col="Gray", 
     xlab="Longitude (radians)", ylab="Latitude (radians)")
points(p)
points(p[p.stationary, ], pch=19, col="Red", cex=0.75)
i <- seq(1, n, by=10)
#
# Because we're near the Equator in this example, buffers will be nearly 
# circular: approximate them.
disk <- function(x, r, n=32) {
  theta <- 1:n / n * 2 * pi
  return (t(rbind(cos(theta), sin(theta))*r + x))
}
r <- 100 / 6378.137  # Buffer radius in radians
apply(p[p.stationary, ], 1, function(x) 
  invisible(polygon(disk(x, r), col="#ff000008", border="#00000040")))
text(p[i,], labels=paste(i), pos=3, offset=1.25, col="Gray")

Çalışma kodu da dahil olmak üzere, izlenen verilerde durağan noktalar bulmak için diğer (istatistiksel temelli) yaklaşımlar için lütfen /mathematica/2711/clustering-of-space-time-data adresini ziyaret edin .


vay, teşekkürler! kafamı bunun etrafında döndürmeyi dört gözle bekliyorum zaman ve çaba için tekrar teşekkürler
Tom Finch
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.