R 查找字符串中连续1的最大数目?

R 查找字符串中连续1的最大数目?,r,R,有没有简单的方法可以获得字符串中最大数量的连续1,如: “0000101110001111111111111100” 一、 当然,我可以用循环来做,但我想避免这样做,因为我的实际数据集有大约500000条记录 提前感谢您的帮助。使用rle: x <- "000010011100011111001111111100" rr <- rle(strsplit(x,"")[[1]]) Run Length Encoding lengths: int [1:9] 4 1 2 3 3 5

有没有简单的方法可以获得字符串中最大数量的连续1,如:
“0000101110001111111111111100”

一、 当然,我可以用循环来做,但我想避免这样做,因为我的实际数据集有大约500000条记录

提前感谢您的帮助。

使用
rle

x <- "000010011100011111001111111100"
rr <- rle(strsplit(x,"")[[1]])

Run Length Encoding
  lengths: int [1:9] 4 1 2 3 3 5 2 8 2
  values : chr [1:9] "0" "1" "0" "1" "0" "1" "0" "1" "0"

使用
rle
比使用正则表达式更慢、更笨拙。在中,当值等于1时,仍然需要提取最大长度

# make some data
set.seed(21)
N <- 1e5
s <- sample(c("0","1"), N*30, TRUE)
s <- split(s, rep(1:N, each=30))
s <- sapply(s, paste, collapse="")
# Thomas' (complete) answer
r <- function(S) {
  sapply(S, function(x) {
    rl <- rle(as.numeric(strsplit(x,"")[[1]]))
    max(rl$lengths[rl$values==1])
  })
}
# using regular expressions
g <- function(S) sapply(gregexpr("1*",S),
   function(x) max(attr(x,'match.length')))
# timing
system.time(R <- r(s))
#    user  system elapsed 
#    6.41    0.00    6.41
system.time(G <- g(s))
#    user  system elapsed 
#    1.47    0.00    1.46
all.equal(R,G)
# [1] "names for target but not for current"
#制作一些数据
种子(21)

N不使用
rle
的另一种快得多的方法是使用连续的0进行拆分,如下所示:

# following thelatemail's comment, changed '0+' to '[^1]+'
strsplit(x, "[^1]+", perl=TRUE)
然后,您可以循环并获得列表中每个元素的最大字符数。这也将比
rle
解决方案更快。而且比@Joshua提供的
gregexpr
解决方案更快。一些基准测试

zz <- function(x) {
    vapply(strsplit(x, "[^1]+", perl=TRUE), function(x) max(nchar(x)), 0L)
}

您尝试过什么(以及来自的其他问题)?我只尝试过使用循环。我有两个循环,一个作为行号上的计数器,从数据集的第一行开始,一直到最后。另一个循环作为连续1个数的计数器。但它效率很低,运行时间也很长。@Thomas,你说得对。我搜索了一下,但什么也没找到。我应该用更好的关键词来搜索。@Arun-我认为这应该是一个单独的答案,而不是编辑。“如果你这样做,我可能会删除我的。”最近的邮件,是的,我现在意识到了。单独张贴。谢谢(托马斯,抱歉弄得一团糟)。如果我想创建一个单独的专栏,我该怎么做?我尝试对一列执行此操作,但所有行的值都相同。有什么建议吗?很好。如果存在除
0
1
以外的字符,则在
strsplit
调用中将
“0+”
替换为
“[^1]”
。稍微慢一点,但可能更安全。是的,你说得对。但我认为这不会影响性能。在我的测试中大约慢了50%。从0.5秒到0.75秒。只是再次进行基准测试。“0+”和“[^1]+”分别需要1.1秒和1.22秒。非常感谢@Arun回答这个问题。感谢@Joshua提供了有用的答案。
zz <- function(x) {
    vapply(strsplit(x, "[^1]+", perl=TRUE), function(x) max(nchar(x)), 0L)
}
g2 <- function(S) vapply(gregexpr("1*",S, perl=TRUE),
   function(x) max(attr(x,'match.length')), 0L)

require(microbenchmark)
microbenchmark(t1 <- zz(unname(s)), t2 <- g(unname(s)), t3 <- g2(unname(s)), times=50)
Unit: seconds
                expr      min       lq   median       uq      max neval
 t1 <- zz(unname(s)) 1.187197 1.285065 1.344371 1.497564 1.565481    50
  t2 <- g(unname(s)) 2.154038 2.307953 2.357789 2.417259 2.596787    50
 t3 <- g2(unname(s)) 1.562661 1.854143 1.914597 1.954795 2.203543    50

identical(t1, t2) # [1] TRUE
identical(t1, t3) # [1] TRUE