从矩阵构建汇总表

时间:2014-05-29 20:46:41

标签: r

我有这个矩阵

mdat <- matrix(c(0,1,1,1,0,0,1,1,0,1,1,1,1,0,1,1,1,1,0,1), nrow = 4, ncol = 5, byrow = TRUE)

    [,1] [,2] [,3] [,4] [,5]
[1,]    0    1    1    1    0
[2,]    0    1    1    0    1
[3,]    1    1    1    0    1
[4,]    1    1    1    0    1

我试图建立T:

     T1 T2 T3
row1  1  2  4
row2  2  2  3
row3  2  5  5
row4  3  1  3
row5  3  5  5
row6  4  1  3
row7  4  5  5

mdat中的每一行: T1显示mdat行号 T2显示mdat列,其中第一个1 T3显示mdat列,其中最后一个连续1。

因此

T中的row1是[1 2 4],因为对于mdat中的第1行,第一个1位于第2列,最后一个连续1位于第4列。

T中的row2是[2 2 3],因为对于mdat中的第2行,第一个1位于第2列,最后一个连续1位于第3列。

这是我的尝试:

for (i in 1:4){ 
 for (j in 1:5) {

   if (mdat[i,j]==1) {T[i,1]<-i;T[i,2]<-j;
cont<-0;
while (mdat[i,j+cont]==1){
    cont<-cont+1;
    T[i,3]<-cont}
}
}
}

2 个答案:

答案 0 :(得分:3)

这是理查德建议使用apply/rle的策略。

xx<-apply(mdat, 1, function(x) {
    r <- rle(x)
    w <- which(r$values==1)
    l <- r$lengths[w]
    s <- cumsum(c(0,r$lengths))[w]+1
    cbind(start=s,stop=s+l-1)
})
do.call(rbind, Map(cbind, row=seq_along(xx), xx))

我们首先使用&#34;值&#34;在每行上找到1的运行。 rle的属性,我们使用&#34;长度&#34;来计算它们的起止位置。属性。我们将这些数据转换为两个列矩阵的列表,每个原始矩阵的列有一个列表项。

现在我们使用Map将行号添加回矩阵,然后我们查看所有结果。这似乎为您提供了

之后的数据
     row start stop
[1,]   1     2    4
[2,]   2     2    3
[3,]   2     5    5
[4,]   3     1    3
[5,]   3     5    5
[6,]   4     1    3
[7,]   4     5    5

答案 1 :(得分:2)

尝试使用Bioconductor IRanges包:

library(IRanges)
r <- unlist(slice(split(Rle(mdat), row(mdat)), 1, rangesOnly=TRUE)))
r

IRanges of length 7
    start end width names
[1]     2   4     3     1
[2]     2   3     2     2
[3]     5   5     1     2
[4]     1   3     3     3
[5]     5   5     1     3
[6]     1   3     3     4
[7]     5   5     1     4

编辑:优化