仅熔化基质中的最高值

时间:2017-07-20 22:32:20

标签: r matrix optimization

我有一个大的方形矩阵,包含每行或每列之间的相关性:

mat <- matrix(rnorm(5000 * 5000), nrow = 5000, dimnames = list(
    paste0("ID", seq_len(5000)), paste0("ID", seq_len(5000))))

我想从这个矩阵中提取前100,000个唯一对(即ID1-ID2与ID2-ID1相同),然后将它们转换为数据帧。目前,我正在使用此代码:

corDat <- reshape2::melt(mat, varnames = c("id.A", "id.B"),
                       value.name = "value", na.rm = T)
corDat <- corDat[as.character(corDat$id.A) < as.character(corDat$id.B),]
corDat <- corDat[order(-corDat$value),]
top_n <- 100000
corDat <- corDat[seq_len(top_n),]

结果:

head(corDat)

           id.A   id.B    value
19316931 ID1931 ID3864 5.658092
14312231 ID2231 ID2863 5.416562
3225529   ID529  ID646 5.357433
3492653  ID2653  ID699 5.297154
17046659 ID1659 ID3410 5.105343
3323364  ID3364  ID665 4.987266    
...

然而,由于矩阵很大,上面的前两个操作(melt矩阵并删除重复对)需要很长时间,通常超过5分钟。我需要将这个操作应用于几百个可变大小的矩形矩阵(通常大于5000x5000)。

我确信必须有更快的方法来提取这些信息,因为我实际上并不需要融合整个矩阵 - 只是与前100,000个值相关联的行和列名称。如何更有效地完成这项工作?

1 个答案:

答案 0 :(得分:1)

这是使用索引的基本R版本:

up <- upper.tri(mat)
inds <- which( up , arr.ind = TRUE )
out <- data.frame( id.A = rownames(mat)[ inds[,1] ] , id.B = rownames(mat)[ inds[,2] ] , value = mat[up] )
#order and select the top ten:
out[order(-out$value),][1:10,]

在我的机器上,这比melt快3.5倍。

我假设您想要矩阵的上三角部分。

请注意,由于多位数字符串比较的工作方式(例如as.character(corDat$id.A) < as.character(corDat$id.B)评估为"ID10" < "ID7"),因此TRUE语句不会选择上三角形部分。