Skip to content

Euclidean Distance in 3 Dimensions

8 messages · Don McKenzie, Patzelt, Edward, David L Carlson +1 more

#
R Community -

I am attempting to write a function that will calculate the distance
between points in 3 dimensional space for unique regions (e.g. localized
brain regions such as the frontal lobe).

For example I'm looking to compare each point in region 45 to every other
region in 45 to establish if they are a distance of 8 or more apart. I can
do this linearly comparing each distance to the previous but this is not
comparing all points.

structure(list(Cluster.Index = c(46L, 46L, 46L, 46L, 46L, 45L,
45L, 45L, 45L, 45L, 44L, 44L, 44L, 44L, 44L, 43L, 43L, 43L, 43L,
43L), Value = c(8.21, 7.96, 7.85, 7.83, 7.8, 5.38, 4.56, 4.5,
4, 3.99, 5.42, 4.82, 4.21, 4.18, 3.91, 4.79, 4.27, 3.24, 3.06,
3.04), x = c(33L, 38L, 37L, 36L, 38L, 47L, 42L, 43L, 44L, 42L,
50L, 41L, 39L, 41L, 44L, 46L, 45L, 45L, 41L, 46L), y = c(15L,
12L, 12L, 13L, 13L, 91L, 84L, 84L, 95L, 96L, 69L, 70L, 65L, 65L,
59L, 41L, 40L, 46L, 44L, 47L), z = c(41L, 38L, 41L, 39L, 33L,
39L, 40L, 42L, 44L, 45L, 34L, 36L, 30L, 35L, 39L, 53L, 47L, 61L,
52L, 57L), X = c(NA, 6.557438524302, 3.16227766016838, 2.44948974278318,
6.32455532033676, 78.7464284904401, 8.66025403784439, 2.23606797749979,
11.2249721603218, 2.44948974278318, 30.2324329156619, 9.2736184954957,
8.06225774829855, 5.3851648071345, 7.81024967590665, 22.8910462845192,
6.16441400296898, 15.2315462117278, 10.0498756211209, 7.68114574786861
)), .Names = c("Cluster.Index", "Value", "x", "y", "z", "X"), row.names =
c(NA,
20L), class = "data.frame")

mainDat <- data.frame()
for(i in 2:nrow(dat)){
tempDist <- (sqrt((dat$x[i] - dat$x[i-1])^2 + (dat$y[i] - dat$y[i-1])^2 +
(dat$z[i] - dat$z[i-1])^2))
dat$X[i] <- c(tempDist)
if(dat$Cluster.Index[i] != dat$Cluster.Index[i-1]){
mainDat <- rbind(mainDat, dat[i,])
}
if((dat$Cluster.Index[i] == dat$Cluster.Index[i-1])) {
if(tempDist > 8){
mainDat <- rbind(mainDat, dat[i,])
}
}
}
#
?dist

from the help

dist {stats}	R Documentation
Distance Matrix Computation

Description

This function computes and returns the distance matrix computed by using the specified distance measure to compute the distances between the rows of a data matrix.

Is this what you want?  Computing on a matrix whose rows are your x, y, and z values?
On Aug 20, 2014, at 1:12 PM, Patzelt, Edward <patzelt at g.harvard.edu> wrote:

            
Don McKenzie
Research Ecologist
Pacific Wildland Fire Sciences Lab
US Forest Service

Affiliate Professor
School of Environmental and Forest Sciences
University of Washington
dmck at uw.edu
#
This function unfortunately does not work in 3d space.

Thoughts?
On Wed, Aug 20, 2014 at 4:57 PM, Don McKenzie <dmck at u.washington.edu> wrote:

            

  
    
#
Ugh sorry.  I misread your message obviously. Cc?ing back to the list (as is the protocol)

I?m surprised no one else has replied. I?m a lightweight compared to others on the list.  It looks as if the dist() function has compiled code, 
which suggests that there is some gnarly linear algebra underneath to speed it up even in 2D. Not for the faint-of-heart to hack.

Others?  ?dist3D??
On Aug 21, 2014, at 11:34 AM, Patzelt, Edward <patzelt at g.harvard.edu> wrote:

            
Don McKenzie
Research Ecologist
Pacific Wildland Fire Sciences Lab
US Forest Service

Affiliate Professor
School of Environmental and Forest Sciences
University of Washington
dmck at uw.edu
#
The dist() function works just fine in 2d or 3d or 100d. Your description of what you want to accomplish is not clear. Your code compares rows 1 and 2, then 2 and 3, then 3 and 4, and so on. You are comparing only adjacent points, but your description makes it sound like you want to compare point 1 to all the other points and see if they are in the same group and over 8 or in another group. If you type the following command you will see that your dat$X is just the diagonal of the distance matrix: 1 with 2, 2 with 3, 3 with 4 etc:

dist(dat[, 3:5])

-------------------------------------
David L Carlson
Department of Anthropology
Texas A&M University
College Station, TX 77840-4352

From: r-help-bounces at r-project.org [mailto:r-help-bounces at r-project.org] On Behalf Of Don McKenzie
Sent: Thursday, August 21, 2014 1:44 PM
To: Patzelt, Edward
Cc: R-help at r-project.org
Subject: Re: [R] Euclidean Distance in 3 Dimensions

Ugh sorry.  I misread your message obviously. Cc?ing back to the list (as is the protocol)

I?m surprised no one else has replied. I?m a lightweight compared to others on the list.  It looks as if the dist() function has compiled code,
which suggests that there is some gnarly linear algebra underneath to speed it up even in 2D. Not for the faint-of-heart to hack.

Others?  ?dist3D??
On Aug 21, 2014, at 11:34 AM, Patzelt, Edward <patzelt at g.harvard.edu<mailto:patzelt at g.harvard.edu>> wrote:

            
Don McKenzie
Research Ecologist
Pacific Wildland Fire Sciences Lab
US Forest Service

Affiliate Professor
School of Environmental and Forest Sciences
University of Washington
dmck at uw.edu<mailto:dmck at uw.edu>





______________________________________________
R-help at r-project.org<mailto:R-help at r-project.org> mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.
#
Your first description is correct with slight modification "compare point 1
to all the other points in that Cluster.Index and see if any of euclidean
distances are greater than 8; do this for each point (i.e. point 2, point
3) in that specific Cluster.Index (i.e. 45)"
On Thu, Aug 21, 2014 at 3:35 PM, David L Carlson <dcarlson at tamu.edu> wrote:

            

  
    
#
So these two commands split the data frame by Cluster.Index and save them as a list, Clusters and then compute distance matrices on each group and save them as a list, Dists:

Clusters <- split(dta, dta$Cluster.Index)
Clusters
Dists <- lapply(Clusters, dist)
Dists

You should be able to process the matrices in each list to get what you want.

David C

From: Patzelt, Edward [mailto:patzelt at g.harvard.edu]
Sent: Thursday, August 21, 2014 2:58 PM
To: David L Carlson
Cc: Don McKenzie; R-help at r-project.org
Subject: Re: [R] Euclidean Distance in 3 Dimensions

Your first description is correct with slight modification "compare point 1 to all the other points in that Cluster.Index and see if any of euclidean distances are greater than 8; do this for each point (i.e. point 2, point 3) in that specific Cluster.Index (i.e. 45)"
On Thu, Aug 21, 2014 at 3:35 PM, David L Carlson <dcarlson at tamu.edu<mailto:dcarlson at tamu.edu>> wrote:
The dist() function works just fine in 2d or 3d or 100d. Your description of what you want to accomplish is not clear. Your code compares rows 1 and 2, then 2 and 3, then 3 and 4, and so on. You are comparing only adjacent points, but your description makes it sound like you want to compare point 1 to all the other points and see if they are in the same group and over 8 or in another group. If you type the following command you will see that your dat$X is just the diagonal of the distance matrix: 1 with 2, 2 with 3, 3 with 4 etc:

dist(dat[, 3:5])

-------------------------------------
David L Carlson
Department of Anthropology
Texas A&M University
College Station, TX 77840-4352

From: r-help-bounces at r-project.org<mailto:r-help-bounces at r-project.org> [mailto:r-help-bounces at r-project.org<mailto:r-help-bounces at r-project.org>] On Behalf Of Don McKenzie
Sent: Thursday, August 21, 2014 1:44 PM
To: Patzelt, Edward
Cc: R-help at r-project.org<mailto:R-help at r-project.org>
Subject: Re: [R] Euclidean Distance in 3 Dimensions

Ugh sorry.  I misread your message obviously. Cc?ing back to the list (as is the protocol)

I?m surprised no one else has replied. I?m a lightweight compared to others on the list.  It looks as if the dist() function has compiled code,
which suggests that there is some gnarly linear algebra underneath to speed it up even in 2D. Not for the faint-of-heart to hack.

Others?  ?dist3D??
On Aug 21, 2014, at 11:34 AM, Patzelt, Edward <patzelt at g.harvard.edu<mailto:patzelt at g.harvard.edu>> wrote:

            
Don McKenzie
Research Ecologist
Pacific Wildland Fire Sciences Lab
US Forest Service

Affiliate Professor
School of Environmental and Forest Sciences
University of Washington
dmck at uw.edu<mailto:dmck at uw.edu>





______________________________________________
R-help at r-project.org<mailto:R-help at r-project.org> mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.



--
Edward H Patzelt | Clinical Science PhD Student
Psychology | Harvard University
#
[I think 'this' is refering to the 'dist' function.]

Can you show how it is not working for you?  I.e., what does it
produce compared to what you want for a given input?

dist() does work on a 3-column (or n-column) matrix or data.frame,
which is how R generally represents 3 dimensional (or n dimensional)
data.  E.g.,

  > d <- data.frame(One=1:3, Two=c(3,5,8), Three=c(4,8,16))
  > d
    One Two Three
  1   1   3     4
  2   2   5     8
  3   3   8    16
  > dist(d)
            1         2
  2  4.582576
  3 13.152946  8.602325
  > as.matrix(dist(d)) # the matrix format makes further compuations easier
            1        2         3
  1  0.000000 4.582576 13.152946
  2  4.582576 0.000000  8.602325
  3 13.152946 8.602325  0.000000
  > which(as.matrix(dist(d))>8, arr.ind=TRUE)
    row col
  3   3   1
  3   3   2
  1   1   3
  2   2   3
  > sqrt(sum((d[,2] - d[,3])^2)) # the 2,3 or 3,2 element, by hand
  [1] 8.602325

I think it would help if you restated your problem.  I found the original
description confusing.  A small example, with the expected output, would
be very helpful.

Bill Dunlap
TIBCO Software
wdunlap tibco.com
On Thu, Aug 21, 2014 at 11:34 AM, Patzelt, Edward <patzelt at g.harvard.edu> wrote: