如何计算由包含x,y的矩阵定义的两点之间的欧氏距离?

时间:2014-07-14 22:13:28

标签: r matrix euclidean-distance

我在欧几里德距离计算中迷失了方向。我发现函数dist2 {SpatialTools}或rdist {fields}来执行此操作,但它们不能按预期工作。

我认为一个点在carthesian系统中有两个坐标,所以[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]

我有两个矩阵: 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]坐标标识的两点之间的距离矢量,但是,使用dist2我得到一个矩阵:

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

我的问题是,哪个数字描述了这个矩阵中A-B和C-D之间真正的欧几里德距离?我误会了什么吗?非常感谢你的每一条建议或任何解释。

4 个答案:

答案 0 :(得分:12)

如果你只想要一个矢量,这样的东西对你有用。

尝试这样的事情:

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(因为这对于像这样的各种任务很容易)。在包的文档中阅读更多相关信息。

答案 1 :(得分:0)

对角线是您正在寻找的。 dist2的输出矩阵显示了所有点之间的距离。输出中的行号对应于第一个输入中的行,输出列对应于第二个输入中的行。这是一个图表,希望它有意义(这是我希望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的第二个点到{{1}的第二个点的距离因此,对角线。

如果您有大量数据,并且只关心相应的数据对,那么直接计算数据会好得多:

x2

如果你有一个全部数据(数百万点),那么像@Shambho建议的> 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 可能值得使用。

答案 2 :(得分:0)

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)

答案 3 :(得分:-1)

您可以随时应用真正的等式(为sqldf包编写,但可以轻松转换):

sum(SQRT(power(a.LONG-b.lon,2)+power(a.LAT-b.lat,2))) AS DISTANCE