2015-09-14 3 views
5

概要二つの列の間の距離を計算する: I魚テレメトリデータセットをクリーンアップしています(すなわち、時間を経て空間座標)data.tableパッケージを使用して(バージョン1.9.5)R(バージョン)でWindows 7 PCでいくつかのデータポイントが間違っている(例えば、遠隔測定装置がエコーを取り込んだ)。魚が生物学的に可能な距離よりも遠くに移動し、外れ値として目立つので、これらの点が間違っていることがわかります。実際のデータセットには、30個の魚からのデータが2,000,000行以上含まれているため、data.tableパッケージを使用しています。問題のdata.table

離れすぎている(つまり、移動距離が最大距離を超えています)点を削除しています。しかし、2-3点のデータ点がクラスターで誤って記録されたため、点を削除した後に点間を移動した距離を再計算する必要があります。現在、私はforというループを持っていますが、最適化されていない可能性が高く、data.tableパッケージの強力なツールの一部が欠けている可能性があります。

テクニカルノートとして、私の空間規模は十分小さく、ユークリッド距離が働き、私の最大距離基準は生物学的に妥当です。

私が助けを求めているところ:私はSOを通して見て、いくつかの役に立つ答えを見つけましたが、私の問題にはまったく合致しません。具体的には、他のすべての回答は、データの1つの列と行の間だけを比較します。このanswer

  1. data.tableを使用して2つの列を比較しますが、1つの変数のみを調べます。

  2. このanswerは有望に見え、Reduceを使用しますが、2つの列でReduceを使用する方法を理解できませんでした。

  3. このanswerは、data.tableのインデックス機能を使用していますが、距離機能で使用する方法を理解できませんでした。

  4. 最後に、answerは、data.tableの機能を示しています。しかし、私はこの関数で2つの変数を使う方法を理解できませんでした。ここで

は私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)]))] 
    } 
} 

答えて

4

あなたは距離を再計算(および不データをコピー)維持なぜ私は少し混乱しているだけではなく、単一のパスで行うので:

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 
+0

私はデータを2回通過していました。なぜなら、私は単一の解決策を見つけることができなかったからです:)。あなたの答えをありがとう! –

+1

ハハ、喜んで助けてください – eddi