2
\$\begingroup\$

I am writing codes to have the Euclidean distance of two matrices and then storing them in a matrix. Could anyone please review this?

a <-matrix(1:2,ncol = 2,nrow = 2)
a
     [,1] [,2]
[1,]    1    1
[2,]    2    2

b <-matrix(3:6,ncol = 2,nrow = 2)
b
     [,1] [,2]
[1,]    3    5
[2,]    4    6

n <-matrix(data = NA)
 for (i in 1:nrow(a)) {
   for (j in 1:nrow(b)) {
    n[i]<-sum(abs(a[i,]-b[j,])^2)
  }
}
n
\$\endgroup\$
2
  • 3
    \$\begingroup\$ something in your code doesn't look correct, maybe you want something like this: stackoverflow.com/questions/35106567/… \$\endgroup\$
    – minem
    Commented May 20, 2018 at 16:49
  • \$\begingroup\$ Also, you're missing the square root. If you install the proxy package, you can do proxy::dist(a, b, method = "Euclidean"). \$\endgroup\$
    – Alexis
    Commented Jun 25, 2018 at 20:42

1 Answer 1

3
\$\begingroup\$

First let's take a quick look at what your code is doing. Your innermost line of code is:

n[i]<-sum(abs(a[i,]-b[j,])^2)

Due to how you've structured your for loops, this is run for times

  1. with i=1 and j=1, setting n[1] to the squared distance between row 1 with a and row 1 of b,
  2. with i=1 and j=2, overwriting n[1] to the squared distance between row 1 of a and row 2 of b,
  3. with i=2 and j=1, setting n[2] to the squared distance between row 2 of a and row 1 of b, and
  4. with i=2 and j=2, overwriting n[2] to the squared distance between row 2 of a and row 2 of b.

So we end up with n = c(34, 20), the squared distances between each row of a and the last row of b.

It seems most likely to me that you are trying to compute the distances between each pair of points (since your n is structured as a vector). In this case, check out what we accomplish with the following, much simpler code:

(a-b)^2
#      [,1] [,2]
# [1,]    4   16
# [2,]    4   16

The resulting matrix is the squared difference of each element in the two matrices. All we need to do is to sum up the rows:

n <- rowSums((a-b)^2)
n
# [1] 20 20

Or if we wanted the actual distance instead of the squared distance:

n <- sqrt(rowSums((a-b)^2))
n
# [1] 4.472136 4.472136

Note that we dramatically simplified the calculation; a nice side benefit is that this code is much faster than using a for loop in R.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.