How do I manipulate/access elements of an instance of "dist" class using core R? How do I manipulate/access elements of an instance of "dist" class using core R? r r

How do I manipulate/access elements of an instance of "dist" class using core R?


There aren't standard ways of doing this, unfortunately. Here's are two functions that convert between the 1D index into the 2D matrix coordinates. They aren't pretty, but they work, and at least you can use the code to make something nicer if you need it. I'm posting it just because the equations aren't obvious.

distdex<-function(i,j,n) #given row, column, and n, return index    n*(i-1) - i*(i-1)/2 + j-irowcol<-function(ix,n) { #given index, return row and column    nr=ceiling(n-(1+sqrt(1+4*(n^2-n-2*ix)))/2)    nc=n-(2*n-nr+1)*nr/2+ix+nr    cbind(nr,nc)}

A little test harness to show it works:

dist(rnorm(20))->testdas.matrix(testd)[7,13]   #row<coldistdex(7,13,20) # =105testd[105]   #same as abovetestd[c(42,119)]rowcol(c(42,119),20)  # = (3,8) and (8,15)as.matrix(testd)[3,8]as.matrix(testd)[8,15]


I don't have a straight answer to your question, but if you are using the Euclidian distance, have a look at the rdist function from the fields package. Its implementation (in Fortran) is faster than dist, and the output is of class matrix. At the very least, it shows that some developers have chosen to move away from this dist class, maybe for the exact reason you are mentioning. If you are concerned that using a full matrix for storing a symmetric matrix is an inefficient use of memory, you could convert it to a triangular matrix.

library("fields")points <- matrix(runif(1000*100), nrow=1000, ncol=100)system.time(dist1 <- dist(points))#    user  system elapsed #   7.277   0.000   7.338 system.time(dist2 <- rdist(points))#   user  system elapsed #  2.756   0.060   2.851 class(dist2)# [1] "matrix"dim(dist2)# [1] 1000 1000dist2[1:3, 1:3]#              [,1]         [,2]         [,3]# [1,] 0.0000000001 3.9529674733 3.8051198575# [2,] 3.9529674733 0.0000000001 3.6552146293# [3,] 3.8051198575 3.6552146293 0.0000000001


as.matrix(d) will turn the dist object d into a matrix, while as.dist(m) will turn the matrix m back into a dist object. Note that the latter doesn't actually check that m is a valid distance matrix; it just extracts the lower triangular part.