R:找到一个连续出现的数字

时间:2018-01-11 17:10:54

标签: r dplyr data.table purrr

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

# 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列中,选择从289到302的天数(使用dat1),找到最长的连续出现1。    重复它,这次选择从dat的303(302 + 1)到343的天数,找到最长的连续出现1。     重复343到353:选择从344(343 + 1)到353的日期,找到最长的连续出现1。

2)对所有列执行此操作

如果我想做1的总和,我可以这样做:

    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功能。我真的很想保留上面的代码 我的其他代码是相同的模式和输出格式适合我的需要,所以如果有人可以建议如何解决它我会很感激。

1 个答案:

答案 0 :(得分:1)

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

然而,由OP创建的样本数据集是矩阵(在它们被强制转换为purrr之前)并且我感到很难找到一种方法来解决基本R中的任务而不使用val:< / p>

要查找向量x中特定值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和子集{{1}}。