A basic/common class in R is called \"dist\"
, and is a relatively efficient representation of a symmetric distance matrix. Unlike a \"matrix\"
object,
This response is really just an extended follow on to Christian A's earlier response. It is warranted because some readers of the question (myself included) may query the dist object as if it were symmetric ( not just (7,13) as below but also (13,7). I don't have edit privileges and the earlier answer was correct as long as the user was treating the dist object as a dist object and not a sparse matrix which is why I have a separate response rather than an edit. Vote up Christian A for doing the heavy lifting if this answer is useful. The original answer with my edits pasted in :
distdex<-function(i,j,n) #given row, column, and n, return index
n*(i-1) - i*(i-1)/2 + j-i
rowcol<-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))->testd
as.matrix(testd)[7,13] #row
But...
distdex(13,7,20) # =156
testd[156] #the wrong answer
Christian A's function only works if i < j. For i = j and i > j it returns the wrong answer. Modifying the distdex function to return 0 when i == j and to transpose i and j when i > j solves the problem so:
distdex2<-function(i,j,n){ #given row, column, and n, return index
if(i==j){0
}else if(i > j){
n*(j-1) - j*(j-1)/2 + i-j
}else{
n*(i-1) - i*(i-1)/2 + j-i
}
}
as.matrix(testd)[7,13] #row