构建对称二进制矩阵

时间:2016-10-24 08:38:44

标签: r loops matrix

我有一个矩阵,例如:

rownames    V1
a   1
c   3
b   2
d   4
y   2
q   4
i   1
j   1
r   3

我想制作一个对称二进制矩阵,它的dimnames与上面矩阵的rownames相同。我想用1&填充这些矩阵。 0以这样的方式,1表示放置变量,在它前面有相同的数字,0表示相反的情况。这个矩阵就像

dimnames    
    a   c   b   d   y   q   i   j   r
a   1   0   0   0   0   0   1   1   0
c   0   1   0   0   0   0   0   0   1
b   0   0   1   0   1   0   0   0   0
d   0   0   0   1   0   1   0   0   0
y   0   0   1   0   1   0   0   0   0
q   0   0   0   1   0   1   0   0   0
i   1   0   0   0   0   0   1   1   0
j   1   0   0   0   0   0   1   1   0
r   0   1   0   0   0   0   0   0   1

有人知道我该怎么办?

2 个答案:

答案 0 :(得分:4)

使用dist

DF <- read.table(text = "rownames    V1
                 a   1
                 c   3
                 b   2
                 d   4
                 y   2
                 q   4
                 i   1
                 j   1
                 r   3", header = TRUE)

res <- as.matrix(dist(DF$V1)) == 0L
#alternatively:
#res <- !as.matrix(dist(DF$V1)) 
#diag(res) <- 0L #for the first version of the question, i.e. a zero diagonal
res <- +(res) #for the second version, i.e. to coerce to an integer matrix
dimnames(res) <- list(DF$rownames, DF$rownames)
#  1 2 3 4 5 6 7 8 9
#1 1 0 0 0 0 0 1 1 0
#2 0 1 0 0 0 0 0 0 1
#3 0 0 1 0 1 0 0 0 0
#4 0 0 0 1 0 1 0 0 0
#5 0 0 1 0 1 0 0 0 0
#6 0 0 0 1 0 1 0 0 0
#7 1 0 0 0 0 0 1 1 0
#8 1 0 0 0 0 0 1 1 0
#9 0 1 0 0 0 0 0 0 1

答案 1 :(得分:3)

您可以使用tablecrossprod执行此操作。

tcrossprod(table(DF))     
#         rownames
# rownames a b c d i j q r y
#        a 1 0 0 0 1 1 0 0 0
#        b 0 1 0 0 0 0 0 0 1
#        c 0 0 1 0 0 0 0 1 0
#        d 0 0 0 1 0 0 1 0 0
#        i 1 0 0 0 1 1 0 0 0
#        j 1 0 0 0 1 1 0 0 0
#        q 0 0 0 1 0 0 1 0 0
#        r 0 0 1 0 0 0 0 1 0
#        y 0 1 0 0 0 0 0 0 1

如果您想要在数据中找到行和列顺序,而不是字母数字,则可以进行子集

tcrossprod(table(DF))[DF$rownames, DF$rownames]

或使用因子

tcrossprod(table(factor(DF$rownames, levels=unique(DF$rownames)), DF$V1)) 

如果您的数据很大或稀疏,您可以使用xtabs中的稀疏矩阵代数,使用类似的方法更改结果表的顺序。

Matrix::tcrossprod(xtabs(data=DF, ~ rownames + V1, sparse=TRUE))