将频率矩阵转换为R中的有序对列表

时间:2014-06-03 01:37:24

标签: r matrix

我们说我有一个3x3的频率值矩阵。该矩阵中的每个单元代表在特定位置检测到的实体的数量(关于这些位置的细节对于我们的目的而言并不重要)。例如,在第1行第1列中检测到0个实体;在第2行第3列中检测到3个实体;等

     [,1] [,2] [,3]
[1,]    0    1    0
[2,]    1    2    3
[3,]    0    1    1

我想将此矩阵转换为nx2数据帧,其中n是在所有位置检测到的实体总数。在这种情况下,应该有9行,因为总共检测到9个实体。在我们创建的数据框中,第1列应包含实体的行索引,第2列应包含实体的列索引。

我们可以使用以下代码来完成此任务,但对于较大的矩阵,此方法非常慢。

mat <- matrix(c(0,1,0,1,2,3,0,1,1), nrow = 3, byrow = TRUE)
x <- rep(NA, 9)
y <- rep(NA, 9)
count <- 0
for(i in 1:3){
    for(j in 1:3){
        while(mat[i,j] > 0){
            count <- count + 1
            x[count] <- i
            y[count] <- j
            mat[i,j] <- mat[i,j] - 1
        }
    }
}
df <- data.frame(x, y)

此代码为我们提供了以下9x2数据框:

x  y
1  2
2  1
2  2
2  2
2  3
2  3
2  3
3  2
3  3

我们解释这个数据框的方式是说在位置(1,2)检测到一个实体,在位置(2,1)检测到一个实体,在位置(2,2)检测到两个实体,等等上。这个输出是正确的,但我更愿意使用更快的方法来获得它。

有更好的方法吗?

1 个答案:

答案 0 :(得分:6)

arr.ind参数提供起始点,即具有非零条目的索引,并且您可以rep() - 按条目值吃它们:

idxs <- which(dat > 0, arr.ind=TRUE)
idxs[ rep(1:nrow(idxs), dat[dat>0]), ]
      row col
 [1,]   2   1
 [2,]   1   2
 [3,]   2   2
 [4,]   2   2
 [5,]   3   2
 [6,]   2   3
 [7,]   2   3
 [8,]   2   3
 [9,]   3   3