对dist()输出进行排序

4
我有一个矩阵 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

这是可以实现的,但我不知道如何做到这一点。

你还没有指定列/行的名称 - David Arenburg
3个回答

4

一种选择是将dist转换为matrix,将上三角的值替换为0,然后进行melt操作,subset非零值,最后基于'value'列进行order

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']),]

1
使用基本的R语言,你可以像这样做:cbind(which(m1!= 0, arr.ind = TRUE), value = m1[m1 != 0])(在前两行之后)。顺便问一下,你从哪里获取了列/行名称? - David Arenburg
@DavidArenburg 谢谢你。这可能需要稍作修改以包括行/列名称。我将 dimnames(m) <- rep(list(LETTERS[1:4]), 2) 进行转换。 - akrun
@ARobertson 我不知道。我的代码是基于原帖作者的示例编写的。 - akrun

1
如果您的dist对象中存在距离值=0
我开始使用akrun发布的解决方案来对dist对象的输出进行排序。但在我的情况下,我确实有距离值= 0。为了避免使用subset步骤丢弃这些值,我首先将上三角转换为NA,然后使用diag还将对角线转换为NA(实际上从另一个程序中获得了对称矩阵)。最后,我使用melt、na.omit和order而不是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

0

使用基本的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]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接