# [R] vectorization of a loop for mahalanobis distance calculation

Sarah Goslee sarah.goslee at gmail.com
Tue Oct 7 19:15:03 CEST 2008

```Hi Frank,

If the way distance() calculates the Mahalanobis distance meets your
needs other than the covariance specification, you can tweak that
_very_ easily. If you use fix(distance) at the command line, you can
edit the source.
change the first line to:
function (x, method = "euclidean", icov)
and under method 4, change the icov calculation to:
if(missing(icov)) {
icov <- solve(cov(x))
}

Alternatively, here's a simplified distanceM function with everything but the
relevant bits deleted. You'll still need to have ecodist loaded.

distanceM <- function (x, method = "mahalanobis", icov)
{
paireddiff <- function(x) {
N <- nrow(x)
P <- ncol(x)
A <- numeric(N * N * P)
A <- .C("pdiff", as.double(as.vector(t(x))), as.integer(N),
as.integer(P), A = as.double(A), PACKAGE = "ecodist")\$A
A <- array(A, dim = c(N, N, P))
A
}
x <- as.matrix(x)
N <- nrow(x)
P <- ncol(x)

if(missing(icov)) {
icov <- solve(cov(x))
}
A <- paireddiff(x)
A1 <- apply(A, 1, function(z) (z %*% icov %*% t(z)))
D <- A1[seq(1, N * N, by = (N + 1)), ]

D <- D[col(D) < row(D)]
attr(D, "Size") <- N
attr(D, "Labels") <- rownames(x)
attr(D, "Diag") <- FALSE
attr(D, "Upper") <- FALSE
attr(D, "method") <- METHODS[method]
class(D) <- "dist"
D
}

Sarah

On Tue, Oct 7, 2008 at 1:05 PM, Frank Hedler <fhedler at googlemail.com> wrote:
> Dear all,
> we just realized something. Sarah's distance function - indeed - calculates
> mahalanobis distance very well. However, it uses the
> observed variance-covariance matrix by default.
> What we actually need (sorry for not stating it clearly in to be able to
> specify which variance-covariance matrix goes into that calculation.
> On Tue, Oct 7, 2008 at 12:44 PM, Sarah Goslee <sarah.goslee at gmail.com>
> wrote:
>>
>> distance() from the ecodist package will calculate Mahalanobis distances.
>>
>> Sarah
>>

--
Sarah Goslee
http://www.functionaldiversity.org

```