R:查找连续出现的数字

R: find consecutive occurrence of a number

首先定义一些函数来按行和按列绑定列表

# a function to append vectors row wise 
rbindlist <- function(list) {
              n <- length(list)
              res <- NULL
              for (i in seq(n)) res <- rbind(res, list[[i]])
              return(res)
            }

 cbindlist <- function(list) {
              n <- length(list)
              res <- NULL
              for (i in seq(n)) res <- cbind(res, list[[i]])
              return(res)
            }

# generate sample data
        sample.dat <- list()  
        set.seed(123)
        for(i in 1:365){
            vec1 <- sample(c(0,1), replace=TRUE, size=5)
            sample.dat[[i]] <- vec1
         }

        dat <- rbindlist(sample.dat)

dat 有五列。每列都是一个位置,一年中有 365 天(365 行),其值为 1 或 0。 我有另一个数据框(见下文),它在 dat.

中的每一列(位置)都有一年中的某些日子
# generate second sample data
      set.seed(123)
      sample.dat1 <- list()  
      for(i in 1:5){
           vec1 <- sort(sample(c(258:365), replace=TRUE, size=4), decreasing = F)
           sample.dat1[[i]] <- vec1
      }

            dat1 <- cbindlist(sample.dat1)

我需要使用 dat1dat 中的天数进行子集计算。下面的例子:

1) 对于位置 1(dat1dat 中的第一列): 在 dat 的第 1 列中,select 从 289 到 302 的天数(使用 dat1),找到连续出现时间最长的 1。 重复它,这次 select 从 303 (302 + 1) 到 dat 的 343 天,找到连续出现时间最长的 1。 重复 343 到 353:select 从 344 (343 + 1) 到 353 的天数,找出连续出现时间最长的 1.

2) 对所有列执行此操作

如果我想求和,我可以这样做:

    dat <- as.tibble(dat)
    dat1 <- as.tibble(dat1)

    pmap(list(dat,dat1), ~ {
       range1 <- ..2[1]
       range2 <- ..2[2]
       range3 <- ..2[3]
       range4 <- ..2[4]

       sum.range1 <- sum(..1[range1:range2]) # this will generate sum between range 1 and range 2
       sum.range2 <- sum(..1[range2:range3]) # this will generate sum between range 2 and range 3
       sum.range3 <- sum(..1[range3:range4]) # this will generate sum between range 3 and range 4

       c(sum.range1=sum.range1,sum.range2=sum.range2,sum.range3=sum.range3) 

    }) 

对于每个范围之间连续出现最长的 1,我想到了使用 rle 函数。示例如下:

  pmap(list(dat,dat1), ~ {
       range1 <- ..2[1]
       range2 <- ..2[2]
       range3 <- ..2[3]
       range4 <- ..2[4]

spell.range1 <- rle(..1[range1:range2]) # sort the data, this shows the longest run of ANY type (0 OR 1)
spell.1.range1 <- tapply(spell.range1$lengths, spell.range1$values, max)[2] # this should select the maximum consequtive run of 1 

spell.range2 <- rle(..1[range2:range3]) # sort the data, this shows the longest run of ANY type (0 OR 1)
spell.1.range2 <- tapply(spell.range2$lengths, spell.range2$values, max)[2] # this should select the maximum consequtive run of 1 

spell.range3 <- rle(..1[range3:range4]) # sort the data, this shows the longest run of ANY type (0 OR 1)
spell.1.range3 <- tapply(spell.range3$lengths, spell.range3$values, max)[2] # this should select the maximum consequtive run of 1

c(spell.1.range1 = spell.1.range1, spell.1.range2 = spell.1.range2, spell.1.range3 = spell.1.range3) 

 })

我收到一个错误,我认为这是因为我没有在这里正确使用 rle 函数。我真的很想保留上面的代码,因为 我的其他代码采用相同的模式,输出格式适合我的需要,所以如果有人可以建议如何修复它,我将不胜感激。

OP 的代码对我有用。因此,如果没有特定的错误消息,就无法理解为什么代码 为 OP 工作。

但是,OP 创建的样本数据集是矩阵(在它们被强制转换为 tibble 之前),我觉得很难找到一种方法来解决 base R 中的任务而不使用 purrr :

要查找向量 x 中特定值 val 的连续出现次数,我们可以使用以下函数:

max_rle <- function(x, val) {
  y <- rle(x)
  len <- y$lengths[y$value == val]
  if (length(len) > 0) max(len) else NA
}

示例:

max_rle(c(0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1), 1)
[1] 4
max_rle(c(0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1), 0)
[1] 2
# find consecutive occurrences in column batches
lapply(seq_len(ncol(dat1)), function(col_num) {
  start <- head(dat1[, col_num], -1L)
  end   <- tail(dat1[, col_num], -1L) - 1
  sapply(seq_along(start), function(range_num) {
    max_rle(dat[start[range_num]:end[range_num], col_num], 1)
  })
})
[[1]]
[1] 8 4 5

[[2]]
[1] 4 5 2

[[3]]
[1] NA  3  4

[[4]]
[1] 5 5 4

[[5]]
[1] 3 2 3

第一个 lapply() 分别遍历 datdat1 的列。第二个 sapply() 循环存储在 dat1 中的行范围并相应地子集 dat