2017-11-18 9 views
1

個々のIDが移動したランバート座標から最大(絶対的で累積ではない)の距離を見つける必要があります。グループごとに可能なすべての座標ペア間の最大距離

Iは、次のデータセットを有する:

  rownum <- c(1,2,3,4,5,6,7,8) 
     ID <- c(1,1,1,1,2,3,3,3) 
     years <- c(1994, 1994, 1995, 1995, 1994, 1998, 1999, 1999) 
     coorx <- c(160501,160507,160507,160508,160638,160402,160402,160707) 
     coory <- c(202549,202727,202727,202488,202701,202586,202586,202548) 
     test <- as.data.frame(cbind(rownum, ID, years, coorx, coory)) 

点はユークリッド距離で既に従って、ランバート72点の座標です。したがって、sqrt((x2-x1)^ 2 +(y2-y1)^ 2)を使用して行のペア間の距離を求める必要があることはわかっています。私が悩んでいるのは、この計算を同時に行っている最中に、個々の個体ごとにすべての行をペアごとに比較して最大距離を見つける必要があるということです。私。 1-2行目、1-3行目、1-4行目、2-3行目、2-4行目などを比較し、max distを抽出します。私はこの結果を新しい列に追加する必要があります(1人あたりすべての行に対して1つの最大値)。

座標(ID2)が1つのみの場合、0またはNAを追加できます。

すべての回答これはグループ間で分割されていないベクトル全体(たとえばOperate on pairs of rows of a data frame)の連続した行間でのみ検出されます。

これにcombn、outer、またはdist関数を適合させる方法はありますか?

この問題の拡張は、特定の年の最初の座標を取得し、それを他の年の最初の座標からの座標と比較することによって、年間の最大距離を見つけることです。しかし、最も重要なのは最初の質問です。

答えて

0

dplyrでこれを行う方法は次のとおりです。基本的には、最初にgroup_by IDを入力してから、selectを使ってrownumとyearsの列を削除します。私はIDを使用して自分自身とデータをマージfull_join。これにより、座標のペアが作成されます。また、1年目から2年目には座標が変更されますが、その逆もありますが、これは問題ありません。maxのみを保持します。次に、私はmutateを使って新しいdist列を作成し、最後にmaxの距離をIDでsummariseにしてください。

test <- as.data.frame(cbind(rownum, ID, years, coorx, coory)) 
test %>% 
    group_by(ID) %>% 
    select(ID,coorx, coory) %>% 
    full_join(.,.,by="ID") %>% 
    mutate(dist=sqrt((coorx.x-coorx.y)^2+(coory.x-coory.y)^2)) %>% 
    summarise(max_dist=max(dist,na.rm=TRUE)) 
# A tibble: 3 x 2 
    ID max_dist 
    <dbl> <dbl> 
1  1 239.0021 
2  2 0.0000 
3  3 307.3581 

あなただけの各年の最初の場所を使用して運動したい場合は、row_number()==1filterを使用する必要があります。

test <- as.data.frame(cbind(rownum, ID, years, coorx, coory)) 
test %>% 
    group_by(ID,years) %>% 
    dplyr::filter(row_number()==1) %>% 
    group_by(ID) %>% 
    select(ID,coorx, coory) %>% 
    full_join(.,.,by="ID") %>% 
    mutate(dist=sqrt((coorx.x-coorx.y)^2+(coory.x-coory.y)^2)) %>% 
    summarise(max_dist=max(dist,na.rm=TRUE)) 

# A tibble: 3 x 2 
    ID max_dist 
    <dbl> <dbl> 
1  1 178.1011 
2  2 0.0000 
3  3 0.0000 

最後に、data.tableと同じことを行う方法です。私は最初にmerge自身のIDを持つデータです。次に、:=演算子を使用して新しいdist列を作成し、最後にIDでmaxの距離だけを保持します。

test <- as.data.table(cbind(ID, coorx, coory)) 
merged <- merge(test,test,by=c("ID"),allow.cartesian=TRUE) 
merged[,dist:=sqrt((coorx.x-coorx.y)^2+(coory.x-coory.y)^2) ] 
merged[,.(max_dist=max(dist,na.rm=TRUE)),by=ID] 

    ID max_dist 
1: 1 239.0021 
2: 2 0.0000 
3: 3 307.3581 
0

IDですべての可能な組み合わせの(SQL話す)ここで、あなたはクロスため、それ自体の上にmergeデータフレームは(すなわち、直積)に参加を自己結合を検討してください。そして、IDによってmaxのためにあなたの式とaggregateあたりの距離を計算します。

merge_df <- merge(test, test, by="ID", suffixes=c("1", "2"))  
merge_df$dist <- with(merge_df, sqrt((coorx2-coorx1)^2+(coory2-coory1)^2)) 

max_dist <- aggregate(dist~ID, merge_df, FUN=max) 
max_dist 
# ID  dist 
# 1 1 239.0021 
# 2 2 0.0000 
# 3 3 307.3581 

そして、最初の年のために、最初に選択し、元のデータフレーム上で集計を実行する、すなわち、head(df)[1]、その後、自己に上記と同様の処理を実行するには、参加する:

year_df <- aggregate(.~ID + years, test, FUN=function(i) head(i)[1]) 

merge_df <- merge(year_df, year_df, by="ID", suffixes=c("1", "2")) 
merge_df$dist <- with(merge_df, sqrt((coorx2-coorx1)^2+(coory2-coory1)^2)) 

max_dist <- aggregate(dist~ID, merge_df, FUN=max) 
max_dist 
# ID  dist 
# 1 1 178.1011 
# 2 2 0.0000 
# 3 3 0.0000 
関連する問題