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

前端 未结 12 1949
傲寒
傲寒 2021-02-02 10:50

A basic/common class in R is called \"dist\", and is a relatively efficient representation of a symmetric distance matrix. Unlike a \"matrix\" object,

12条回答
  •  离开以前
    2021-02-02 11:01

    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

提交回复
热议问题