我有这个矩阵
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}
}
}
}
答案 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
编辑:优化