2017-03-23 1 views
0

canberra distance - inconsistent results과 비슷하게 필자는 거리 계산을 직접 작성했지만 훨씬 더 많은 데이터 집합에 대해이 작업을 수행하고 결과에서 거리 행렬을 작성하려고합니다.캔버라 거리 매트릭스 수동 계산

내 초기 기능은 내 데이터 프레임의 행의 모든 ​​쌍에이 기능을 적용하고이 계산으로부터의 거리 행렬을 작성하고 싶습니다 지금

canb.dist <- function(x, j) sum((abs(x-j))/(abs(x)+abs(j)))

입니다. 의 내 데이터가 있다고 가정 해 봅시다 :이 다음 부분에 어려움을 겪고있어

data<-data.frame(replicate(500,sample(1:100,50,rep=TRUE))) 

, 어떻게 행의 모든 ​​쌍에이를 적용하고 본질적으로 모방

dist(data,method="canberra") 

나는했습니다 매트릭스를 작성의 시도 :

for (y in 1:50) 
{ 
    for (z in 2:50) 
    { 
    canb.dist(data[y,1:500],data[z,1:500]) 
    } 
} 

하지만 분명하지 않습니다. 모든 쌍을 통과하여 거리 매트릭스를 수동으로 복제하는 방법이 있습니까?

답변

1

combn을 사용하여 행 쌍을 만들고 각 쌍의 캔버라 거리를 계산할 수 있습니다. 그런 다음 dist 클래스로 변환이 완벽하게 작동

#OP's data 
set.seed(1) 
canb.dist <- function(x, j) sum((abs(x-j))/(abs(x)+abs(j))) 
data <- data.frame(replicate(500,sample(1:100,50,rep=TRUE))) 
refdist <- dist(data, method="canberra") 

#convert to matrix 
mat <- as.matrix(data) 

#sequence of row indices 
rowidx <- seq_len(nrow(mat)) 

#calculate OP's Canberra dist for each pair of rows 
triangular <- combn(rowidx, 2, function(x) c(x[1], x[2], canb.dist(mat[x[1],], mat[x[2],]))) 

#construct the matrix given the indices and values using Matrix library, 
#convert into a matrix before converting into a dist class 
#the values refer to the diagonal, lower triangular and upper triangular 
library(Matrix) 
ansdist <- as.dist(as.matrix(sparseMatrix(
    i=c(rowidx, triangular[1,], triangular[2,]), 
    j=c(rowidx, triangular[2,], triangular[1,]), 
    x=c(rep(0, length(rowidx)), triangular[3,], triangular[3,]) 
))) 

#idea from http://stackoverflow.com/questions/17375056/r-sparse-matrix-conversion/17375747#17375747 
range(as.matrix(refdist) - as.matrix(ansdist)) 
+0

스파 스 Matrix 패키지를 사용하여 매트릭스에 인덱스와 값을 변환합니다. 나는 그것이 잘되기 위해 해결되는만큼 복잡 할 것이라고 생각하지 않고 있었지만, 대단히 감사합니다! – coderX