将矩阵转换为R中的三个定义列

时间:2016-07-15 15:10:23

标签: r matrix

鉴于m

m <- structure(c(5, 1, 3, 2, 1, 4, 5, 2, 5, 1, 1, 5, 1, 4, 0, 4, 5, 
5, 3, 2, 0, 0, 3, 0, 3, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0), .Dim = c(7L, 
5L))

     # [,1] [,2] [,3] [,4] [,5]
# [1,]    5    2    0    0    0
# [2,]    1    5    4    3    0
# [3,]    3    1    5    0    0
# [4,]    2    1    5    3    0
# [5,]    1    5    3    2    0
# [6,]    4    1    2    3    0
# [7,]    5    4    0    0    0

考虑元素1,它出现在5行(2, 3, 4, ,5, 6)中,相应的列式索引为(1, 2, 2, 1, 2)。我想拥有以下内容:

1 2 1
1 3 2
1 4 2
1 5 1
1 6 2

作为另一个例子,考虑元素2,它出现在4行(1, 4, 5, 6)中,相应的列式索引是(2, 1, 4, 3),我们有:

1 2 1
1 3 2
1 4 2
1 5 1
1 6 2
2 1 2
2 4 1
2 5 4
2 6 3

我想要的是所有1-5的n*3矩阵。 优选在碱基R

3 个答案:

答案 0 :(得分:3)

我们可以将whicharr.ind=TRUE

一起使用
cbind(val= 1, which(m==1, arr.ind=TRUE))
#     val row col
#[1,]   1   2   1
#[2,]   1   5   1
#[3,]   1   3   2
#[4,]   1   4   2
#[5,]   1   6   2

对于多个案例,正如@RHertel所提到的

for(i in 1:5) print(cbind(i,which(m==i, arr.ind=TRUE)))

lapply

do.call(rbind, lapply(1:2, function(i) {
        m1 <-cbind(val=i,which(m==i, arr.ind=TRUE))
        m1[order(m1[,2]),]}))
#      val row col
#[1,]   1   2   1
#[2,]   1   3   2
#[3,]   1   4   2
#[4,]   1   5   1
#[5,]   1   6   2
#[6,]   2   1   2
#[7,]   2   4   1
#[8,]   2   5   4
#[9,]   2   6   3

正如OP提到的base R解决方案,上述内容会有所帮助。但是,万一,如果有人想要一个紧凑的解决方案,

library(reshape2)
melt(m)

然后对感兴趣的值进行子集化。

答案 1 :(得分:2)

转换它的一种便捷方法是使用sparseMatrix库中的Matrix,因为您所需的输出非常接近稀疏矩阵的表示形式:

library(Matrix)
summary(Matrix(m, sparse = T))
# 7 x 5 sparse Matrix of class "dgCMatrix", with 23 entries 
#    i j x
# 1  1 1 5
# 2  2 1 1
# 3  3 1 3
# 4  4 1 2
# 5  5 1 1
# 6  6 1 4
# 7  7 1 5
# 8  1 2 2
# 9  2 2 5
# 10 3 2 1
# 11 4 2 1
# 12 5 2 5
# 13 6 2 1
# 14 7 2 4
# 15 2 3 4
# 16 3 3 5
# 17 4 3 5
# 18 5 3 3
# 19 6 3 2
# 20 2 4 3
# 21 4 4 3
# 22 5 4 2
# 23 6 4 3

更好地看待它:

summary(Matrix(m, sparse = T)) %>% dplyr::arrange(x)
#    i j x
# 1  2 1 1
# 2  5 1 1
# 3  3 2 1
# 4  4 2 1
# 5  6 2 1
# 6  4 1 2
# 7  1 2 2
# 8  6 3 2
# 9  5 4 2
# 10 3 1 3
# 11 5 3 3
# 12 2 4 3
# 13 4 4 3
# 14 6 4 3
# 15 6 1 4
# 16 7 2 4
# 17 2 3 4
# 18 1 1 5
# 19 7 1 5
# 20 2 2 5
# 21 5 2 5
# 22 3 3 5
# 23 4 3 5

答案 2 :(得分:2)

只需使用rowcol

> data.frame(m=as.vector(m), row=as.vector(row(m)), col=as.vector(col(m)))
   m row col
1  5   1   1
2  1   2   1
3  3   3   1
4  2   4   1
5  1   5   1
...

根据需要进行子集,排序和打印。

> tmp <- out[order(out$m, out$row), ]
> print(subset(tmp, m==1), row.names=FALSE)
 m row col
 1   2   1
 1   3   2
 1   4   2
 1   5   1
 1   6   2