2011-01-25 53 views
1

我有一个75 x 75方阵。除标签以外的所有值都是小数。 我想要得到所有具有高于或低于我设置的截断值的标签对。 说,我有以下Sorting a Square Matrix

 A  B  C  D 
A 1  0.2 0.43 0.16 
B 0.2 1  0.86 0.28 
C 0.43 0.86 1  0.76 
D 0.16 0.28 0.76 1 

我想

B C 0.86 
C D 0.76 
A C 0.43 

我怎么能去了解它(没有得到重复的)?

由于

+0

您对分拣还是切入感兴趣? – Aaron

回答

3

首先,您需要将每个值转换为具有一行的表示;一种方法是转换为矩阵,然后转换为data.frame。为了避免重复,在转换为数据帧之前将下三角形(可能包括对角线)设置为NA,然后取数据框中其值不是NA的子集。

mtx <- matrix(rnorm(16), 4, 4, dimnames = list(LETTERS[1:4], LETTERS[1:4])) 
mtx[lower.tri(mtx, diag=TRUE)] <- NA 
dx <- as.data.frame(as.table(mtx)) 
dx <- subset(dx, !is.na(Freq)) 

然后,您可以根据需要从结果数据框中获取子集。

> subset(dx, Freq>0) 
    Var1 Var2  Freq 
5  A B 1.9564158 
9  A C 1.7188939 
14 B D 0.1848542 
2

的一种方法是使用来自reshape包FN的melt修订以避免在对称矩阵的重复,和排序的最终结果)。

> mtx <- matrix(round(10*rnorm(16)), 
       4, 4, dimnames = list(LETTERS[1:4], LETTERS[1:4])) 
> mtx[ upper.tri(mtx)] <- NA 
> mtx 
    A B C D 
A -7 NA NA NA 
B 23 17 NA NA 
C 6 -2 20 NA 
D -23 8 15 -6 
> require(reshape) 
> df <- cbind(data.frame(Row = rownames(mtx)), as.data.frame(mtx)) 
> df.m <- melt(df, id = 'Row', variable_name = 'Col') 
> df.m 
    Row Col value 
1 A A -7 
2 B A 23 
3 C A  6 
4 D A -23 
5 A B NA 
6 B B 17 
7 C B -2 
8 D B  8 
9 A C NA 
10 B C NA 
11 C C 20 
12 D C 15 
13 A D NA 
14 B D NA 
15 C D NA 
16 D D -6 
> filt <- subset(df.m, value < 0) 
> filt[order(filt$value),] 
    Row Col value 
4 D A -23 
1 A A -7 
16 D D -6 
7 C B -2 

当然你可以用任何你想要的方式格式化结果,例如,

> cat(with(filt, paste(Row, Col, value, '\n'))) 
A A -7 
D A -23 
C B -2 
D D -6 
+0

这不会消除重复项(如果我们正在处理像OP中的例子那样的对称)。如何做到这一点只是一个练习。 :) –

+0

非常感谢。但是,如何删除重复项。例如'A-B'和'B-A'。另外我怎么排序这个子集,按降序排列,保持Row Col对? – y2p

+0

请参阅我的更新 –

0
library(fBasics) 
Z <- Triang(X) 
data.frame(t(apply(which(Z >= 0.43 & Z < 1 ,arr.ind = T),1, 
    function(y) c(rownames(Z)[y[1]],colnames(Z)[y[2]],Z[y[1],y[2]])))) 

X1 X2 X3 
A A C 0.43 
B B C 0.86 
C C D 0.76 
0

与基体和截止

m <- matrix(rnorm(16), 4, 4, dimnames = list(LETTERS[1:4], LETTERS[1:4])) 
cut <- 0 

指标满足您的标准值,并用它来提取所需的价值观和行的名称。事后排序

i <- lower.tri(m, diag=TRUE) * m > cut 
df <- data.frame(Row=rownames(m)[row(m)[i]], Col=colnames(m)[col(m)[i]], 
       Val=m[i]) 
df[order(df$Val),]