Nancy
Nancy

Reputation: 101

Calculate euclidean distance

I have data where rows are points and columns are coordinates x,y,z.

enter image description here

I'd like to calculate euclidean distance between points in couple, as 3-4, 11-12, 18-19 and so on... for example, I dont' need distance between 3 and 11, 12, 18 The problem is that I have to analize 1074 tables with 1000 rows or more, so I'm searching a way to do it automatically, maybe considering tha fact that I want to calculate distance between an odd number and the even following one. I don't care too much about the output format, but pls consider that after I have to select only distances <3.2, so a dataframe format will be great.

Upvotes: 1

Views: 1868

Answers (2)

Rui Barradas
Rui Barradas

Reputation: 76641

Here is a function that can be applied to a data.frame or matrix holding the data.

DistEucl <- function(X){
  i <- cumsum(seq_len(nrow(X)) %% 2 == 1)
  sapply(split(X, i), function(Y){
    sqrt(sum((Y[1, ] - Y[2, ])^2))
  })
}

DistEucl(df1)
#       1        2        3        4 
#1.229293 1.234273 1.245567 1.195319 

With the data in DaveArmstrong's answer, the results are the same except for a names attribute in the above function's return value.

out2 <- DistEucl(df)
all.equal(out, out2)
#[1] "names for current but not for target"

identical(out, unname(out2))
#[1] TRUE

Data in the question

x <- c(13.457, 13.723, 15.319, 15.713, 18.446, 19.488, 19.762, 19.743)
y <- c(28.513, 29.656, 28.510, 27.342, 28.827, 28.24, 29.841, 30.942)
z <- c(40.513, 40.147, 43.281, 43.218, 43.095, 43.443, 40.094, 40.559)

df1 <- data.frame(x, y, z)

Upvotes: 0

DaveArmstrong
DaveArmstrong

Reputation: 22034

How about something like this:

First, I'll make some fake data

set.seed(4304)
df <- data.frame(
  x = runif(1000, -1, 1), 
  y = runif(1000, -1, 1), 
  z = runif(1000, -1,1)
)

Make a sequence of values from 1 to the number of rows of your dataset by 2s.

s <- seq(1, nrow(df), by=2)

Use sapply() to make the distance between each pair of points.

out <- sapply(s, function(i){
  sqrt(sum((df[i,] - df[(i+1), ])^2))
})

Organize the distances into a data frame

res <- data.frame(
  pair = paste(rownames(df)[s], rownames(df)[(s+1)], sep="-"), 
  dist=out)
head(res)
#     pair     dist
# 1   1-2 1.379992
# 2   3-4 1.303511
# 3   5-6 1.242302
# 4   7-8 1.257228
# 5  9-10 1.107484
# 6 11-12 1.392247

Upvotes: 3

Related Questions