我有一个向量,例如x,其中仅包含整数012。例如;

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)或者我们可以将tabulaterleid一起使用

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/

10-12 22:33