我们说我有一个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)检测到两个实体,等等上。这个输出是正确的,但我更愿意使用更快的方法来获得它。
有更好的方法吗?
答案 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