【问题标题】:Building a symmetric binary matrix构建对称二进制矩阵
【发布时间】:2017-03-05 23:17:59
【问题描述】:

我有一个矩阵,例如:

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

我想制作一个对称二进制矩阵,它的暗名与上述矩阵的行名相同。我想用 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

有人知道我该怎么做吗?

【问题讨论】:

  • 前面具有相同数字的第一个矩阵的每个行名将在上面的第二个矩阵中得到 1。例如,“b”、“y”前面有数字 2,所以我将 1 放在“b”和“y”数组的第二个矩阵中。并将 0 用于“a”和“b”的数组 bcz 他们前面没有相同的值@ZheyuanLi
  • 你说得对,这是个错误。

标签: r loops matrix


【解决方案1】:

使用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

【讨论】:

  • @ZheyuanLi 是解决问题的好方法!我建议您做出回复,因为这对许多人来说都很有价值!
  • 谢谢@Roland,我想如果我将 res 矩阵的直径设为 1,那将是正确的答案。真的谢谢你。
  • @minoo 我不明白你的评论。我已经复制了您的预期输出。什么是矩阵的“直径”?编辑:没关系。查看我的编辑。
  • 如果您将您的答案作为回复让我更好地理解,我将不胜感激。 @z
  • @ZheyuanLi 当然。我需要对更高效的版本进行基准测试。可能取决于大小。对于大输入,无论如何我都会返回一个稀疏矩阵。
【解决方案2】:

您可以使用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))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-03
    • 1970-01-01
    • 2014-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-30
    相关资源
    最近更新 更多