web-dev-qa-db-ja.com

x、yを含む行列で定義された2点間のユークリッド距離を計算する方法

ユークリッド距離計算で私は非常に迷っています。これを行う関数dist2 {SpatialTools}またはrdist {fields}を見つけましたが、期待どおりに動作しません。

デカルト系では1つの点に2つの座標があると思います。したがって、[x、y]です。 2つのポイント(行で定義)間の距離を測定するには、2つのポイントに4つの座標が必要なので、ポイントA:[x1、y1]ポイントB:[x2、y2]

ポイントの調整:

Points position

A[0,1]
B[0,0] 
C[1,1]
D[1,1]

私は2つの行列を持っています:x1(行によって定義されたAとCがそこにあります)とx2(BとDを含む)。マトリックスで書かれました:

library("SpatialTools")
x1<-matrix(c(0,1,1,1), nrow = 2, ncol=2, byrow=TRUE)
x2<-matrix(c(0,0,1,1), nrow = 2, ncol=2, byrow=TRUE)

だから私は得る

> x1
     [,1] [,2]
[1,]    0    1    #(as xy coordinates of A point)
[2,]    1    1    #(same for C point)

> x2
     [,1] [,2]
[1,]    0    0    #(same for B point)
[2,]    1    1    #(same for D point)

間のユークリッド距離を計算するには

A <-> B  # same as x1[1,] <-> x2[1,]
C <-> D  # same as x1[2,] <-> x2[2,]

私はEuclidDistを取得すると仮定します:

> x1                           x2                         EuclidDist
     [,1] [,2]                      [,1] [,2]
[1,]    0    1    #A         [1,]    0    0    #B             1
[2,]    1    1    #B         [2,]    1    1    #D             0

[x、y]座標で識別される2点間の距離のベクトルを取得したいのですが、dist2マトリックスを取得します。

> dist2(x1,x2)
         [,1] [,2]
[1,] 1.000000    1
[2,] 1.414214    0

私の質問は、この数値から、A-BとC-Dの間の実際のユークリッド距離を表す数値はどれですか?私は何かを誤解していますか?アドバイスや説明をありがとうございました。

7
maycca

ベクトルだけが必要な場合は、このようなものがうまくいきます。

このようなものを試してください:

euc.dist <- function(x1, x2) sqrt(sum((x1 - x2) ^ 2))

library(foreach)
foreach(i = 1:nrow(x1), .combine = c ) %do% euc.dist(x1[i,],x2[i,])

これはどの次元でも機能します。

Foreachを使用したくない場合は、単純なループを使用できます。

dist <- NULL
for(i in 1:nrow(x1)) dist[i] <- euc.dist(x1[i,],x2[i,])
dist

ただし、foreachをお勧めします(このようなさまざまなタスクを実行するのは非常に簡単だからです)。詳しくはパッケージのドキュメントを読んでください。

13
Shambho
library(rgdal)

library(sp)

##**COORDINATES** DATAFRAME THAT CONTENT THE LATITUDE (LAT) AND LONGITUDE 
##(LON) IN THE COORDINATE REFERENT SYSTEM (CRS) WGS84.

coordinates(COORDINATES) <- ~ LON + LAT

proj4string(COORDINATES) <- CRS("+proj=longlat +datum=WGS84") #ASSIGN THE CRS

Zone <- input$Zone   #UTM ZONE FOR YOUR COUNTRY

COORDINATES <- spTransform(COORDINATES, CRS(paste("+proj=utm", " +zone=", 
                           Zone, " +ellps=WGS84", " +datum=WGS84", " 
                           +units=m", sep="")))  #REPROJECT THE CRS
COORDINATES <- as.data.frame(COORDINATES)
X <- COORDINATES$LON  #EXTRACT THE LOGITUDE VECTOR
Y <- COORDINATES$LAT  #EXTRACT THE LATITUDE VECTOR
MX1 <- X %*% t(X) #CREATE A MATRIX FOR LONGITUDE VECTOR
MX2 <- matrix(rep(t(X),nrow(COORDINATES)), ncol = nrow(COORDINATES), 
              nrow = nrow(COORDINATES)) #CREATE A MATRIX FOR REPEAT LONGITUDE VECTOR
MX <- MX1/MX2 #DEFENITIVE MATRIX FOR LONGITUDE VECTORS
MX <- abs((MX-MX2)**2) #SQUARE SUM OF LONGITUDE VECTORS
colnames(MX)<- paste(COORDINATES$STATION) #ASSIGN COLNAMES
rownames(MX)<- paste(COORDINATES$STATION) #ASSIGN ROWNAMES
MY1 <- Y %*% t(Y) #CREATE A MATRIX FOR LATITUDE VECTOR
MY2 <- matrix(rep(t(Y), nrow(COORDINATES)), ncol = nrow(COORDINATES), 
              nrow = nrow(COORDINATES)) #CREATE A MATRIX FOR REPEAT LATITUDE VECTOR
MY <- MY1/MY2 #DEFENITIVE MATRIX FOR LATITUDE VECTORS
MY <- abs((MY-MY2)*2) #SQUARE SUM OF LONGITUDE VECTORS
colnames(MY)<- paste(COORDINATES$STATION) #ASSIGN COLNAMES
rownames(MY)<- paste(COORDINATES$STATION) #ASSIGN ROWNAMES
EUCLIDEAND <- round((sqrt(MX+MY)/1000), digits = 0) #EUCLIDEAN DISTANCE FOR THESE COORDINATES
EUCLIDEAND <- as.data.frame(EUCLIDEAND)
0
VALIZCANOS

対角線はあなたが探しているものです。 dist2の出力行列は、すべてのポイント間の距離を示します。出力の行番号は最初の入力の行に対応し、出力の列は2番目の入力の行に対応します。ここに図があります、それが意味をなすことを願っています(これは、私がStack OverflowでMathJaxをサポートしたいと思っていることです):

dist2( A_x A_y     C_x C_y      ( AC  AD
       B_x B_y  ,  D_x D_y )  =   BC  BD ) 

dist2(   x1     ,     x2   )  =   result

あなたのケースでは、x1の最初の点からx2の最初の点までの距離が必要で、次にx1の2番目の点までx2の2番目の点までの距離が必要です。したがって、対角線。

大量のデータがあり、対応するペアのみに関心がある場合は、これを直接計算する方がはるかに良いでしょう。

> x1 <- matrix(c(0, 1, 1, 1), ncol = 2, byrow = T)
> x2 <- matrix(c(0, 0, 1, 1), ncol = 2, byrow = T)
> sqrt(rowSums((x1 - x2)^2))
[1] 1 0

whole lotのデータ(何百万ものポイント)がある場合、@ Shambhoが示唆するようにforeachを使用する価値があります。

0
Gregor Thomas