【问题标题】:Transpose non-duplicated edge list into symmetrical matrix将非重复边列表转置为对称矩阵
【发布时间】:2020-06-30 16:03:46
【问题描述】:

我有一个包含相似值的边缘列表,我需要将其转置为对称矩阵。例如,我的原始数据位于格式如下的数据框中:

example <- data.frame(Source = c(0,4,2,2,5,0,1,3,0,10,6,11,7,2),
                  Target = c(1,6,12,13,13,14,14,15,17,17,20,23,24,25),
                  Similarity = c(0.004,0.0009,0.007,0.02,0.0011,0.0018,0.011,0.0013,0.006,0.005,0.0006,0.005,0.0026,0.0013))

我需要以某种方式将其放入规则所在的矩阵中:

  1. “源”x“目标”之间的交集 = 相似度
  2. IF “源” == “目标” THEN 1.00
  3. 如果“源”x“目标”值的组合没有相似度得分,则用 0 填充交集

最后,数据应该是这样的:

     0      1     2     3     4     5
0   1.0   0.004   0     0     0     0
1  0.004   1.0    0     0     0     0
2    0      0    1.0    0     0     0
3    0      0     0    1.0    0     0
4    0      0     0     0    1.0    0
5    0      0     0     0     0    1.0

实际的矩阵不会那么稀疏,大约有 30,000 行 x 30,000 列。我不确定如何处理这个问题。我可以很容易地将现有数据转换为矩阵格式。我可以很容易地用 0 填充缺失值。但是将原始数据转换为对称矩阵并用 1.0 填充对角线,而所有其他缺失值都用 0 填充,这超出了我的能力范围。

编辑:也许更简单的方法是“我如何从这些数据中制作对称矩阵”

example <- data.frame(Source = c(0,0,0,0,1,1,1,1),
                      Target = c(1,2,3,4,2,3,4,5),
                      Similarity = c(0.004,0.0009,0.007,0.02,0.0011,0.0018,0.011,0.006))

【问题讨论】:

  • Obed,您是否能够从您的样本数据中将您想要的输出变成实际想要的输出?目前很难知道行名和列名的来源。您的示例数据中没有 Target 等于零。我们是否假设应该有一个,因为对角线全是 1?
  • @AllanCameron 这是困难的一部分。原始数据没有对角线的数据(1,1;2,2;3,3;等)。同样,如果它有 1,2,那么它不会有 2,1。所以上面想要的输出实际上就是我想要的。我只是将其截断为 5,而不是一直到 25 以节省空间。
  • @AllanCameron 我刚刚添加了另一个示例。也许它更清楚?
  • 我想我明白了。看我的回答。

标签: r matrix


【解决方案1】:

您可以使用diag 获取单位矩阵,然后用循环对称地填充单元格。我们必须向所有索引添加一个,因为您的矩阵是零索引的。请注意,此示例以科学计数法打印第一列,但您可以看到它与第一行相同。

mat <- diag(max(c(example$Source, example$Target)) + 1)

for(i in 1:nrow(example))
{
  mat[example$Source[i] + 1, example$Target[i] + 1] <- example$Similarity[i]
  mat[example$Target[i] + 1, example$Source[i] + 1] <- example$Similarity[i]
}

dimnames(mat) <- list(Source = 0:max(example), Target = 0:max(example))

mat
#>       Target
#> Source     0      1      2      3     4     5
#>      0 1e+00 0.0040 0.0009 0.0070 0.020 0.000
#>      1 4e-03 1.0000 0.0011 0.0018 0.011 0.006
#>      2 9e-04 0.0011 1.0000 0.0000 0.000 0.000
#>      3 7e-03 0.0018 0.0000 1.0000 0.000 0.000
#>      4 2e-02 0.0110 0.0000 0.0000 1.000 0.000
#>      5 0e+00 0.0060 0.0000 0.0000 0.000 1.000

reprex package (v0.3.0) 于 2020 年 6 月 30 日创建

【讨论】:

  • 这是一个很酷的解决方案。您将如何标记输出矩阵的行/列?例如“1”而不是 [1,]。我最终会将此矩阵用于 PCA 和/或 TSNE,并希望使用行名来标记结果图上的标记。
  • @Obed 是的!具有讽刺意味的是,这就是我在回答您的最后一个问题时向您展示的内容,您今天早些时候没有接受!我在这里再次包含它。
  • 太棒了,谢谢!我不是故意不接受你之前的回答。还有另一个答案也有效。没想到这样做会不接受你的!
【解决方案2】:

您可以使用Matrix

例如

library(Matrix)

A <- sparseMatrix(i = example$Source + 1, 
                  j = example$Target + 1,
                  x = example$Similarity, symmetric = TRUE)
diag(A) <- 1


head(A)
6 x 26 sparse Matrix of class "dgCMatrix"
                                                                                                 
[1,] 1.000 0.004 . . . . .      . . . . . .     .      0.0018 .      . 0.006 . . . . . . . .     
[2,] 0.004 1.000 . . . . .      . . . . . .     .      0.0110 .      . .     . . . . . . . .     
[3,] .     .     1 . . . .      . . . . . 0.007 0.0200 .      .      . .     . . . . . . . 0.0013
[4,] .     .     . 1 . . .      . . . . . .     .      .      0.0013 . .     . . . . . . . .     
[5,] .     .     . . 1 .  9e-04 . . . . . .     .      .      .      . .     . . . . . . . .     
[6,] .     .     . . . 1 .      . . . . . .     0.0011 .      .      . .     . . . . . . . .     

如果你愿意,可以通过 as.matrix(A)A 强制转换为普通矩阵

【讨论】:

  • 有没有办法给输出矩阵分配暗名?例如,我尝试了dimnames(A) &lt;- list(Source = unique(example$Source), Target = unique(example$Target)),但得到一个错误
  • @Obed 在sparseMatrix 函数中有一个名为 dimnames 的参数。调查一下
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-13
  • 1970-01-01
  • 2011-01-08
  • 1970-01-01
  • 1970-01-01
  • 2020-01-30
相关资源
最近更新 更多