对 dist() 的输出进行排序

sorting the output of dist()

我有一个矩阵m

m <- matrix ( 
  c( 2, 1, 8, 5,
     7, 6, 3, 4,
     9, 3, 2, 8,
     1, 3, 7, 4),
  nrow  = 4,
  ncol  = 4,
  byrow = TRUE)

rownames(m) <- c('A', 'B', 'C', 'D')

现在,我想根据各自的距离对 m 的行进行排序,所以我使用 dist()

dist_m <- dist(m)

dist_m 是,打印时

          A         B         C
B  8.717798
C  9.899495  5.477226
D  2.645751  7.810250 10.246951

因为我想订购它,所以我尝试 sort(dist_m) 打印

[1]  2.645751  5.477226  7.810250  8.717798  9.899495 10.246951

这几乎就是我想要的。但如果它还打印了两行的名称,其中一个数字是距离,我会更高兴,比如

 2.645751  A  D
 5.477226  B  C
 7.810250  B  D
 8.717798  A  B
 9.899495  A  C
10.246951  C  D

这当然是可能的,但我不知道如何实现。

一个选项是将 dist 转换为 matrix,将上三角值替换为 0,meltsubset 非零值,以及然后 order 基于 'value' 列。

m1 <- as.matrix(dist_m)
m1[upper.tri(m1)] <- 0
library(reshape2)
m2 <- subset(melt(m1), value!=0)
m2[order(m2$value),3:1]
#         value Var2 Var1
#4   2.645751    A    D
#7   5.477226    B    C
#8   7.810250    B    D
#2   8.717798    A    B
#3   9.899495    A    C
#12 10.246951    C    D

或者@David Arenburg 在获得 'm1'

后建议的 base R 选项
 m2 <- cbind(which(m1!=0, arr.ind=TRUE), value= m1[m1!=0])
 m2[order(m2[,'value']),]

使用基数 R:

dm <- as.matrix(dist_m)
df <- data.frame(data = c(dm),
                 column = c(col(dm)),
                 row = c(row(dm)))

# get only one triangle
df <- df[df$row > df$column, ]

# put in order
df[order(df$data), ]

# for letters, add this
df$row <- LETTERS[df$row]
df$column <- LETTERS[df$column]

如果你的 dist 对象中有距离值 = 0

我开始使用 akrun 发布的解决方案对 dist 对象的输出进行排序,但在我的例子中,我的距离值确实 = 0。为了避免使用 subset 丢弃这些步骤,我首先将上三角形转换为 NA,然后将对角线也转换为 NA,使用 diag(实际上是从另一个程序获得的对称矩阵)。最后,我使用了 meltna.omitorder:

而不是 subset
library(reshape2)

#create matrix
 m <- matrix ( 
 c( 2, 1, 8, 5,
    2, 1, 8, 5,
    9, 3, 2, 8,
    1, 3, 7, 4),
    nrow  = 4,
    ncol  = 4,
    byrow = TRUE)

rownames(m) <- c('A', 'B', 'C', 'D')

# use dist
dist_m <- dist(m)
dist_m 

# A and B are identical
             A         B         C
B  0.000000                    
C  9.899495  9.899495          
D  2.645751  2.645751 10.246951

m1 <- as.matrix(dist_m)
m1[upper.tri(m1)] <- NA
diag(m1) <- NA
m2 <- melt(m1)
na.omit(m2[order(m2$value),3:1])

因此,保留了 A 和 B 之间的成对距离值:

       value Var2 Var1
2   0.000000    A    B
4   2.645751    A    D
8   2.645751    B    D
3   9.899495    A    C
7   9.899495    B    C
12 10.246951    C    D