首页 > 解决方案 > 检测具有连续 1/TRUE 的行序列何时开始和结束 R dplyr

问题描述

我需要检测ice由另一个变量排序的变量行的位置,该变量day具有 5 个或更多连续行TRUE

da <- tibble(day=1:365,ice=runif(365)>.8)
da$ice[140:143] <- TRUE
da$ice[150:156] <- TRUE
da$ice[180:184] <- TRUE

day我在 data.frame 中添加了一些噪音,但是当变量上有 5 个或更多TRUEs时,我需要检测第一个块的第一天ice,最后一个块的最后一天,在示例中为day150 和day184 .

我会使用这样的循环

first_day <- 0
for(i in 1:(nrow(da)-5))
{
  if(sum(da$ice[i:(i+5)])==5){

    first_day <- da$day[i]
    print(first_day)
  } 
}

这只是第一次尝试效果不佳,但无法弄清楚如何使用 dplyr 或没有循环的 base R 来做到这一点。

标签: rdplyr

解决方案


我们根据'ice'的值创建一个分组变量run-length-id,然后'ice'filterall值为TRUE并且行数(n())大于或等于5的行,ungroup以及slice第一行和最后一行

library(dplyr)
library(data.table)
da %>% 
   group_by(grp = rleid(ice)) %>%
   filter(all(ice), n() >= 5) %>%
   ungroup %>%
   slice(c(1, n()))

-输出

# A tibble: 2 x 3
#    day ice     grp
#  <int> <lgl> <int>
#1   150 TRUE     46
#2   184 TRUE     58

或者一个选项data.table

library(data.table)
range(setDT(da)[, day[all(ice) & .N >= 5], rleid(ice)]$V1)
#[1] 150 184

推荐阅读