चलो इसे सरल टुकड़ों में तोड़ दें। ऐसा करने से, सभी काम आसानी से परीक्षण किए गए कोड की सिर्फ आधा दर्जन लाइनों में पूरा हो जाता है।
सबसे पहले, आपको दूरियों की गणना करने की आवश्यकता होगी। क्योंकि डेटा भौगोलिक निर्देशांक में हैं, यहाँ एक गोलाकार डेटम पर दूरी की गणना करने के लिए एक फ़ंक्शन है (हैवेर्सिन फॉर्मूला का उपयोग करके):
#
# 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)))
}
यदि आप चाहें तो इसे अपने पसंदीदा कार्यान्वयन के साथ बदलें (जैसे कि एक दीर्घवृत्त डेटा का उपयोग करके)।
अगला, हमें प्रत्येक "आधार बिंदु" (staionarity के लिए जाँच की जा रही है) और इसके अस्थायी पड़ोस के बीच की दूरी की गणना करने की आवश्यकता होगी। यह बस dist
पड़ोस में लागू करने की बात है:
#
# 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, ...))
तीसरा - यह महत्वपूर्ण विचार है - स्थिर बिंदुओं को 11 बिंदुओं के पड़ोस का पता लगाकर पाया जाता है जिनकी पंक्ति में कम से कम पांच होते हैं जिनकी दूरी पर्याप्त रूप से छोटी होती है। आइए हम बूलियन मानों के एक तार्किक सरणी के भीतर सच्चे मूल्यों के सबसे लंबे समय तक चलने की लंबाई निर्धारित करके इसे थोड़ा और सामान्य रूप से लागू करें:
#
# 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)))
(हम झूठे मूल्यों के स्थानों का पता लगाते हैं, और उनके अंतरों की गणना करते हैं: ये गैर-झूठे मूल्यों के बाद की लंबाई हैं। ऐसी सबसे बड़ी लंबाई वापस आ गई है।)
चौथा, हम max.subsequence
स्थिर बिंदुओं का पता लगाने के लिए आवेदन करते हैं।
#
# 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
वे सभी उपकरण हैं जिनकी हमें आवश्यकता है।
एक उदाहरण के रूप में, आइए कुछ दिलचस्प डेटा बनाएं जिसमें स्थिर बिंदुओं के कुछ क्लैंप हों। मैं भूमध्य रेखा के पास एक यादृच्छिक चलना ले जाऊंगा।
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)
अनुक्रम में बिंदुओं के सरणियों lon
और lat
निर्देशांक में निर्देशांक होते हैं n
। रेडियन में पहली बार परिवर्तित होने के बाद हमारे उपकरण को लागू करना सीधा है:
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))
तर्क p[max(1,i-5):min(n,i+5), ]
कहता है कि आधार समय से 5 समय कदम या जहां तक आधार बिंदु से 5 समय कदम आगे बढ़ने की बात है p[i,]
। सहित k=5
एक पंक्ति है कि आधार बिंदु के 100 किमी के भीतर हैं में 5 या अधिक की एक श्रृंखला के लिए देखने के लिए कहते हैं। (100 किमी का मान डिफ़ॉल्ट के रूप में सेट किया गया था is.stationary
लेकिन आप इसे यहां ओवरराइड कर सकते हैं।)
आउटपुट p.stationary
एक तार्किक वेक्टर है जो स्थिरता का संकेत देता है: हमारे पास वही है जो हम लिए आए हैं। हालाँकि, प्रक्रिया की जाँच करने के लिए डेटा और इन परिणामों को प्लॉट करना सबसे अच्छा है, बजाय मानों के सरणियों का निरीक्षण करना। निम्नलिखित प्लॉट पर मैं मार्ग और अंक दिखाता हूं। हर दसवें बिंदु को लेबल किया जाता है, ताकि आप अनुमान लगा सकें कि स्टेशनरी क्लंप के भीतर कितने ओवरलैप हो सकते हैं। स्थिर बिंदु उन्हें उजागर करने के लिए और उनके 100 किलोमीटर के बफ़रों से घिरे हुए ठोस लाल रंग में बदल जाते हैं।
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")
ट्रैक किए गए डेटा में स्थिर बिंदुओं को खोजने के लिए अन्य (सांख्यिकीय-आधारित) दृष्टिकोणों के लिए, वर्किंग कोड सहित, कृपया /mathematica/2711/clustering-of-space-time-data पर जाएं ।