我在欧几里德距离计算中迷失了方向。我发现函数dist2 {SpatialTools}或rdist {fields}来执行此操作,但它们不能按预期工作。
我认为一个点在carthesian系统中有两个坐标,所以[x,y]。 要测量2个点之间的距离(由行定义),我需要2个点的4个坐标,所以 A点:[x1,y1] B点:[x2,y2]
积分协调:
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之间真正的欧几里德距离?我误会了什么吗?非常感谢你的每一条建议或任何解释。
答案 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