ความใกล้ชิดในอวกาศและเวลา


10

ฉันมีข้อมูลบางจุดซึ่งแสดงถึงตำแหน่ง lat-lon รายวันของสัตว์พร้อมการประทับเวลาที่เกี่ยวข้อง

ฉันต้องการระบุทุกจุดที่ STATIONARY = TRUE จุดหนึ่งมีคุณสมบัติเป็นนิ่งถ้าบัฟเฟอร์ 100km รอบมันทับซ้อนกันเพิ่มเติม (พูด) 5 จุดที่อยู่ติดกันชั่วคราว ดังนั้นถ้าวันที่ 10เป็นจุดสนใจของฉันฉันต้องการถามว่า 5 วันที่อยู่ติดกันชั่วคราวนั้นอยู่ในระยะ 100km ของจุดนี้หรือไม่ หากวัน 5,6,7,8 & 9; หรือวัน 11,12,13,14 และ 15; หรือวัน 8,9,11,12,13 (ฯลฯ ) อยู่ในบัฟเฟอร์จากนั้น StationARY = TRUE อย่างไรก็ตามหากวันที่ 5,7,9,11 และ 13 อยู่ในบัฟเฟอร์ แต่ไม่ใช่วันที่เป็นทางเลือก (คู่) ในระหว่างนั้นให้ระบุว่า STATIONARY = FALSE

ฉันคิดว่าการย้ายบัฟเฟอร์หน้าต่างบางชนิดจะช่วยแก้ปัญหานี้ แต่ฉันไม่รู้วิธีใช้สิ่งนี้

ฉันพยายามที่จะแก้ปัญหานี้ทั้งใน ArcGIS และ R แต่ก็ไม่มีคลื่นสมองมาก่อน นี่เป็นวิธีที่ใกล้เคียงที่สุดที่ฉันต้องแก้ไข แต่มันก็ไม่ค่อยเหมาะสมฉันไม่คิดว่า: การระบุจุดต่อเนื่องภายในบัฟเฟอร์ที่ระบุ

นี่คือข้อมูลจำลองที่ใกล้เคียงกับโครงสร้างข้อมูลของฉัน (ในความเป็นจริงฉันมีที่ตั้งสองวันต่อวัน (เที่ยงวันและเที่ยงคืน) โดยที่สถานที่บางแห่งหายไป - แต่ฉันจะกังวลในภายหลัง)

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
คำถาม? สมมติว่า 10 คะแนนทั้งหมดอยู่ในบัฟเฟอร์และคุณมีการแยกวันที่ (เริ่มจากวันที่ 1) ของ 1-3-4-12-13-20-21-22-29-30 จากนั้นคุณบอกว่าคุณเป็นเพียงจุดเลือกที่น่าสนใจ นั่นคือในวัน 1,2,3,4 และ 12
Hornbydd

ไม่ฉันสนใจเฉพาะวันที่ 1-4 หากสัตว์ 'ทิ้ง' บัฟเฟอร์แล้วส่งกลับในวันที่ 12 (หรือวันที่ 6) ดังนั้นจะ 'ยกเลิก' ช่วงเวลาที่หยุดนิ่ง - นั่นคือสัตว์จะต้องอยู่ในบัฟเฟอร์ในวันที่ 1-2-3-4-5 สำหรับ จุดที่อยู่ตรงกลางของบัฟเฟอร์ที่จะนับ ทำให้รู้สึก? ฉันไม่แน่ใจว่าตัวเอง ..
Tom Finch

1
เพียงเพื่อตรวจสอบว่าจุดที่น่าสนใจคือวันที่ 7 คุณจะได้รับคะแนนความสนใจที่อยู่ในระยะ 100 กิโลเมตรสำหรับวันที่ 7,8,9,10 และ 11 หรือไม่
Hornbydd

จะมีการเลือกจุด 7 เป็นจุดคงที่ถ้าวัน 8,9,10, 11 และ 12 มีระยะทาง 100 กม. หรือวัน 5,6,8,9,10 ดังนั้นจุดใดจุดหนึ่งจะถูกเลือกถ้ามีจุด 5 จุดที่อยู่ติดกันชั่วคราว (5 วันก่อนหน้า, 5 วันต่อมาหรืออีกสองสามวันข้างใดข้างหนึ่ง) อยู่ภายในบัฟเฟอร์ ฉันคิดว่าหน้าต่างเคลื่อนไหวเป็นวิธีที่ดีที่สุดในการกำหนดแนวคิด สำหรับจุดโฟกัสแต่ละจุดที่เกิน 5 วันในอดีต / อนาคตสามารถถูกลืมได้ ผมอาจมีการปรับปรุงคำถามเดิมของฉันเป็นตอนนี้ผมเข้าใจมันมากขึ้นอีกนิด ...
ทอมฟินช์

รูปแบบของข้อมูลคืออะไร? ตัวอย่างเช่นคุณมีแต่ละครั้ง / สถานที่เป็นจุดเวกเตอร์ในรูปร่างไฟล์และตารางแอตทริบิวต์ที่เก็บเวลาหรือไม่ หรือแต่ละครั้ง / สถานที่จัดเก็บแยกกันในรูปร่างที่แตกต่างกัน? ข้อมูลไม่ได้อยู่ในรูปแบบเชิงพื้นที่และอยู่ในไฟล์ Excel หรือไม่? การรู้สิ่งนี้จะช่วยเราตอบ

คำตอบ:


12

ลองแบ่งมันเป็นชิ้น ๆ การทำเช่นนี้จะทำให้งานทั้งหมดสำเร็จในเพียงครึ่งโหลของรหัสที่ทดสอบได้ง่าย

ก่อนอื่นคุณจะต้องคำนวณระยะทาง เนื่องจากข้อมูลอยู่ในพิกัดทางภูมิศาสตร์นี่คือฟังก์ชันเพื่อคำนวณระยะทางในรูปทรงกลม (โดยใช้สูตร 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)))
}

แทนที่สิ่งนี้ด้วยการนำไปใช้งานที่คุณชื่นชอบหากคุณต้องการ (เช่นอันที่ใช้ดาต้ารูปวงรี)

ต่อไปเราจะต้องคำนวณระยะทางระหว่าง "จุดฐาน" แต่ละจุด (กำลังตรวจสอบความมั่นคง) และพื้นที่ใกล้เคียงชั่วคราว นั่นเป็นเพียงเรื่องของการนำ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บอกว่าจะมองหาลำดับ 5 หรือมากกว่าในแถวที่อยู่ในระยะ 100 กม. จากจุดฐาน (ค่าของ 100 km ถูกตั้งค่าเป็นค่าเริ่มต้นใน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")

อื่น ๆ (สถิติ-based) วิธีการหาจุดหยุดนิ่งในการติดตามข้อมูลรวมทั้งรหัสการทำงานกรุณาเยี่ยมชม/mathematica/2711/clustering-of-space-time-data


ว้าวขอบคุณ! หวังว่าจะได้รับหัวของฉันรอบนี้ ขอบคุณอีกครั้งสำหรับเวลาและความพยายามของคุณ
Tom Finch
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.