Sự gần gũi trong không gian và thời gian


10

Tôi có một số dữ liệu điểm đại diện cho các vị trí lat-lon hàng ngày của động vật, với dấu thời gian liên quan.

Tôi muốn xác định tất cả các điểm trong đó VĂN PHÒNG = TRUE. Một điểm đủ điều kiện là đứng yên nếu một vùng đệm 100km xung quanh nó chồng lên thêm 5 điểm (giả sử) 5 điểm liền kề theo thời gian . Vì vậy, nếu ngày 10 là điểm quan tâm của tôi, tôi muốn hỏi liệu 5 ngày liền kề có nằm trong vùng đệm 100km của điểm này không. Nếu ngày 5,6,7,8 & 9; HOẶC ngày 11,12,13,14 & 15; HOẶC ngày 8,9,11,12,13 (v.v.) nằm trong bộ đệm, sau đó TRẠM = TRUE. Tuy nhiên, nếu ngày 5,7,9,11 & 13 nằm trong bộ đệm, nhưng không phải là ngày (chẵn) thay thế ở giữa, thì TRẠM = FALSE

Tôi nghĩ rằng một số loại bộ đệm cửa sổ di chuyển sẽ cung cấp giải pháp, nhưng tôi không biết làm thế nào để thực hiện điều này.

Tôi đã cố gắng giải quyết vấn đề này trong cả ArcGIS và R, nhưng cho đến nay vẫn chưa có sóng não. Đây là giải pháp gần nhất mà tôi có với một giải pháp, nhưng nó không hoàn toàn phù hợp, tôi không nghĩ: Xác định các điểm liên tiếp trong một bộ đệm được chỉ định

Đây là một số dữ liệu giả, gần bằng cấu trúc dữ liệu của tôi (mặc dù trong thực tế tôi có hai lần vị trí hàng ngày (giữa trưa và nửa đêm) với một số vị trí bị thiếu - nhưng tôi sẽ lo lắng về điều đó sau)

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
Câu hỏi? Giả sử tất cả 10 điểm nằm trong bộ đệm và bạn có một khoảng cách ngày (bắt đầu từ ngày 1) từ 1-3-4-12-13-20-21-22-29-30 thì bạn có nói rằng bạn chỉ quan tâm đến việc chọn điểm đó là trong ngày 1,2,3,4 & 12?
Hornbydd

Không, tôi chỉ quan tâm đến ngày 1-4. Nếu con vật 'rời khỏi bộ đệm rồi quay trở lại vào ngày 12 (hoặc ngày 6), thì điều đó sẽ' hủy bỏ 'giai đoạn đứng yên đó - tức là con vật phải ở trong bộ đệm vào ngày 1-2-3-4-5 cho điểm ở trung tâm của bộ đệm được tính. Có lý? Tôi không chắc bản thân mình ..
Tom Finch

1
Chỉ cần kiểm tra, nếu điểm quan tâm là ngày 7 thì bạn sẽ có điểm quan tâm nào nằm trong phạm vi 100Km trong các ngày 7,8,9,10 & 11?
Hornbydd

Điểm 7 sẽ được chọn làm điểm dừng nếu các ngày 8,9,10, 11 & 12 bị héo 100km. Hoặc ngày 5,6,8,9,10. Vì vậy, bất kỳ một điểm nào cũng được chọn nếu bất kỳ 5 điểm liền kề tạm thời nào khác (5 ngày trước đó, 5 ngày tiếp theo hoặc một vài ngày ở hai bên) đều nằm trong vùng đệm. Tôi nghĩ rằng cửa sổ di chuyển là cách tốt nhất để khái niệm nó. Đối với mỗi điểm 'tiêu điểm', bất kỳ điểm nào quá 5 ngày vào quá khứ / tương lai đều có thể bị lãng quên. Tôi có thể cập nhật câu hỏi ban đầu của mình, vì bây giờ tôi đã hiểu thêm một chút ...
Tom Finch

Định dạng của dữ liệu là gì? Ví dụ: bạn có mỗi thời gian / vị trí là một điểm vectơ trong một shapefile và một bảng thuộc tính lưu trữ thời gian không? Hoặc mỗi thời gian / địa điểm được lưu trữ riêng biệt trong các shapefile khác nhau? Là dữ liệu thậm chí không ở định dạng không gian địa lý và chỉ đơn giản là trong một tệp Excel? Biết điều này sẽ giúp chúng tôi trả lời.

Câu trả lời:


12

Hãy chia nó thành những mảnh đơn giản. Bằng cách làm như vậy, tất cả các công việc được hoàn thành chỉ trong nửa tá dòng mã được kiểm tra dễ dàng.

Đầu tiên, bạn sẽ cần tính khoảng cách. Vì dữ liệu nằm trong tọa độ địa lý, đây là một hàm để tính khoảng cách trên mốc dữ liệu hình cầu (sử dụng công thức Haversine):

#
# 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)))
}

Thay thế điều này bằng cách thực hiện yêu thích của bạn nếu bạn muốn (chẳng hạn như sử dụng một mốc thời gian hình elip).

Tiếp theo, chúng ta sẽ cần tính khoảng cách giữa mỗi "điểm gốc" (đang được kiểm tra tính ổn định) và vùng lân cận tạm thời của nó. Đó đơn giản chỉ là vấn đề áp dụng distcho khu phố:

#
# 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, ...))

Thứ ba - đây là ý tưởng chính - các điểm dừng được tìm thấy bằng cách phát hiện các vùng lân cận 11 điểm có ít nhất năm điểm liên tiếp có khoảng cách đủ nhỏ. Chúng ta hãy thực hiện điều này một chút chung hơn bằng cách xác định độ dài của chuỗi giá trị thực dài nhất trong một mảng logic của các giá trị boolean:

#
# 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)))

(Chúng tôi tìm vị trí của các giá trị sai , theo thứ tự và tính toán sự khác biệt của chúng: đây là độ dài của các giá trị không sai. Độ dài lớn nhất được trả về.)

Thứ tư, chúng tôi áp dụng max.subsequenceđể phát hiện các điểm dừng.

#
# 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

Đó là tất cả các công cụ chúng ta cần.


Ví dụ, hãy tạo một số dữ liệu thú vị có một vài điểm dừng. Tôi sẽ đi bộ ngẫu nhiên gần Xích đạo.

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)

Các mảng lonlatchứa tọa độ, tính bằng độ, của các nđiểm theo thứ tự. Áp dụng các công cụ của chúng tôi rất đơn giản sau lần đầu tiên chuyển đổi thành radian:

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))

Đối số p[max(1,i-5):min(n,i+5), ]nói rằng hãy nhìn xa tới 5 bước thời gian hoặc tiến xa tới 5 bước thời gian từ điểm gốc p[i,]. Bao gồm k=5nói để tìm kiếm một chuỗi từ 5 trở lên liên tiếp trong phạm vi 100 km từ điểm cơ sở. (Giá trị 100 km được đặt làm mặc định is.stationarynhưng bạn có thể ghi đè lên đây.)

Đầu ra p.stationarylà một vectơ logic biểu thị sự ổn định: chúng ta có những gì chúng ta đã đến. Tuy nhiên, để kiểm tra quy trình, tốt nhất là vẽ sơ đồ dữ liệu và các kết quả này thay vì kiểm tra các mảng giá trị. Trên sơ đồ sau tôi chỉ ra tuyến đường và các điểm. Mỗi điểm thứ mười được dán nhãn để bạn có thể ước tính có bao nhiêu điểm có thể trùng lặp trong các cụm đứng yên. Các điểm dừng được vẽ lại bằng màu đỏ đặc để làm nổi bật chúng và được bao quanh bởi bộ đệm 100 km của chúng.

Nhân vật

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")

Đối với các cách tiếp cận khác (dựa trên thống kê) để tìm các điểm dừng trong dữ liệu được theo dõi, bao gồm cả mã làm việc, vui lòng truy cập https://mathIALa.stackexchange.com/questions/2711/clustering-of-space-time-data .


Ồ cảm ơn nhé! mong nhận được đầu của tôi xung quanh này. cảm ơn một lần nữa vì thời gian và công sức của bạn
Tom Finch
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.