我有一个向量,例如x
,其中仅包含整数0
,1
和2
。例如;
x <- c(0,1,0,2,0,0,1,0,0,1,0,0,0,1,0)
我想从中提取出每个“模式”中出现零的次数。在这个简单的示例中,它自己发生3次,
00
两次,000
一次,所以我想输出以下内容:0 3
00 2
000 1
我的实际数据集非常大(向量中有1000-2000个元素),至少在理论上,连续零的最大数量为
length(x)
最佳答案
1)我们可以使用rleid
中的data.table
data.table(x)[, strrep(0, sum(x==0)) ,rleid(x == 0)][V1 != "",.N , V1]
# V1 N
#1: 0 3
#2: 00 2
#3: 000 1
2)或者我们可以使用
tidyverse
library(tidyverse)
tibble(x) %>%
group_by(grp = cumsum(x != 0)) %>%
filter(x == 0) %>%
count(grp) %>%
ungroup %>%
count(n)
# A tibble: 3 x 2
# n nn
# <int> <int>
#1 1 3
#2 2 2
#3 3 1
3)或者我们可以将
tabulate
与rleid
一起使用tabulate(tabulate(rleid(x)[x==0]))
#[1] 3 2 1
基准测试
通过在@SymbolixAU的数据集中检查
system.time
system.time({
tabulate(tabulate(rleid(x2)[x2==0]))
})
# user system elapsed
# 0.03 0.00 0.03
与
Rcpp
函数相比,上面的还不错 system.time({
m <- zeroPattern(x2)
m[m[,2] > 0, ]
})
# user system elapsed
# 0.01 0.01 0.03
使用
microbenchmark
,删除了消耗更多时间的方法(基于@SymbolixAU的比较),并启动了一个新的比较。还要注意,这里并不是苹果与苹果完全一样,但是它仍然非常相似,因为在先前的比较中,存在data.table
的开销以及一些格式来复制OP的预期输出microbenchmark(
akrun = {
tabulate(tabulate(rleid(x2)[x2==0]))
},
G = {
with(rle(x2), table(lengths[values == 0]))
},
sym = {
m <- zeroPattern(x2)
m[m[,2] > 0, ]
},
times = 5, unit = "relative"
)
#Unit: relative
# expr min lq mean median uq max neval cld
# akrun 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 5 a
# G 6.049181 8.272782 5.353175 8.106543 7.527412 2.905924 5 b
# sym 1.385976 1.338845 1.661294 1.399635 3.845435 1.211131 5 a
关于r - 查找连续零的分布,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/49772395/