我有一个矩阵
mat <- matrix(c(64,76,0,0,78,35,45,0,0,4,37,0,66,46,0,0,0,0,3,0,71,0,28,97,0,30,55,65,116,30,18,0,0,143,99,0,0,0,0,0), nrow=4, byrow=T)
mat
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] 64 76 0 0 78 35 45 0 0 4
[2,] 37 0 66 46 0 0 0 0 3 0
[3,] 71 0 28 97 0 30 55 65 116 30
[4,] 18 0 0 143 99 0 0 0 0 0
我想创建一个列表,该列表计算非零值之间零出现的次数
[[1]]
[1] 2 2
[[2]]
[1] 1 4 1
[[3]]
[1] 1 1
[[4]]
[1] 2 5
答案 0 :(得分:5)
您只需要rle
> apply(mat, 1, function(x) {
rle(x)$length[rle(x)$values == 0]
})
[[1]]
[1] 2 2
[[2]]
[1] 1 4 1
[[3]]
[1] 1 1
[[4]]
[1] 2 5
答案 1 :(得分:2)
您可以使用rle
来计算连续数字的数量
mat <- matrix(c(64,76,0,0,78,35,45,0,0,4,37,0,66,46,0,0,0,0,3,0,71,0,28,97,0,30,55,65,116,30,18,0,0,143,99,0,0,0,0,0), nrow=4, byrow=T)
apply(mat,1,function(x) {
value = rle(x==0)
value$length[value$values]
})
答案 2 :(得分:1)
再一个
setNames(object = lapply(X = data.frame(t(mat)),
FUN = function(x)
with(rle(x == 0), lengths[values])),
nm = NULL)
#[[1]]
#[1] 2 2
#[[2]]
#[1] 1 4 1
#[[3]]
#[1] 1 1
#[[4]]
#[1] 2 5
答案 3 :(得分:0)
如果由于某种原因您有一个包含许多行的矩阵,并且需要更快地执行此操作(不太可能,我知道),则可以使用以下方法
library(dplyr)
rle(c(t(mat))) %>%
do.call(what = data.frame) %>%
mutate(mrow = (cumsum(lengths) - 1) %/% ncol(mat)) %>%
{split(.$lengths[!.$values], .$mrow[!.$values])}
# $`0`
# [1] 2 2
#
# $`1`
# [1] 1 4 1
#
# $`2`
# [1] 1 1
#
# $`3`
# [1] 2 5
基准
mat <- mat[sample(nrow(mat), 1e6, T),]
f1 <- function(mat){
apply(mat, 1, function(x) {
with(rle(x), lengths[values == 0])
})
}
f2 <- function(mat){
rle(c(t(mat))) %>%
do.call(what = data.frame) %>%
mutate(mrow = (cumsum(lengths) - 1) %/% ncol(mat)) %>%
{split(.$lengths[!.$values], .$mrow[!.$values])}
}
microbenchmark::microbenchmark(f1(mat), f2(mat), times = 10)
# Unit: seconds
# expr min lq mean median uq max neval
# f1(mat) 28.346335 28.978307 30.633423 30.720702 31.504075 35.049800 10
# f2(mat) 3.683452 3.916681 4.099936 4.086634 4.250613 4.482668 10