计算data.table中两行之间的距离

Ric*_*son 5 r data.table

问题摘要:我正在使用Windows 7 PC上的(版本)data.table软件包(版本1.9.5)清理鱼类遥测数据集(即空间坐标随时间变化)R.一些数据点是错误的(例如,遥测设备拾取了回声).我们可以说这些点是错误的,因为鱼比生物可能的距离移动了更远的距离并且作为异常值脱颖而出.实际数据集包含来自30条单独鱼类的超过2,000,000行数据,因此使用了该data.table包.

我正在移除相距太远的点(即,行进的距离大于最大距离).但是,我需要重新计算在移除点之后在点之间行进的距离,因为2-3个数据点有时会在群集中被错误记录.目前,我有一个for循环来完成工作,但可能远非最佳,我知道我可能会错过包中的一些强大工具data.table.

作为技术说明,我的空间尺度足够小,欧几里德距离起作用,我的最大距离标准是生物学合理的.

我寻求帮助的地方:我已经查看了SO并找到了几个有用的答案,但没有一个完全符合我的问题.具体而言,所有其他答案仅将一列数据与行之间进行比较.

  1. 答案使用两行进行比较data.table,但仅查看一个变量.

  2. 这个答案看起来很有前途和用途Reduce,但我无法弄清楚如何使用Reduce两列.

  3. 这个答案使用了索引功能data.table,但我无法弄清楚如何将它与距离函数一起使用.

  4. 最后,这个答案证明了它的roll功能data.table.但是,我无法弄清楚如何使用这个函数的两个变量.

这是我的MVCE:

library(data.table)
## Create dummy data.table
dt <- data.table(fish = 1,
                 time = 1:6,
                 easting = c(1, 2, 10, 11, 3, 4),
                 northing = c(1, 2, 10, 11, 3, 4))
dt[ , dist := 0]

maxDist = 5

## First pass of calculating distances 
for(index in 2:dim(dt)[1]){
    dt[ index,
       dist := as.numeric(dist(dt[c(index -1, index),
                list(easting, northing)]))]
}

## Loop through and remove points until all of the outliers have been
## removed for the data.table. 
while(all(dt[ , dist < maxDist]) == FALSE){
    dt <- copy(dt[ - dt[ , min(which(dist > maxDist))], ])
    ## Loops through and recalculates distance after removing outlier  
    for(index in 2:dim(dt)[1]){
        dt[ index,
           dist := as.numeric(dist(dt[c(index -1, index),
                    list(easting, northing)]))]
    }
}
Run Code Online (Sandbox Code Playgroud)

edd*_*ddi 6

我有点困惑,为什么要不断重新计算距离(并不必要地复制数据)而不是只执行一次:

last = 1
idx = rep(0, nrow(dt))
for (curr in 1:nrow(dt)) {
  if (dist(dt[c(curr, last), .(easting, northing)]) <= maxDist) {
    idx[curr] = curr
    last = curr
  }
}

dt[idx]
#   fish time easting northing
#1:    1    1       1        1
#2:    1    2       2        2
#3:    1    5       3        3
#4:    1    6       4        4
Run Code Online (Sandbox Code Playgroud)