识别 id 和 segment 中的一系列连续数字

identify series of consecutive numbers within id and segment

我有一个面板,dfL,我在其中尝试识别变量 PM 中的 ID id 和段 shift 中的系列连续数字.我正在寻找包含数字 -11 并且长度为 4 或更多的系列连续数字。

下面是我用数据说明的情况,

# install.packages(c("tidyverse"), dependencies = TRUE)
library(tibble)

我最初有这样的宽格式数据,

dfa <- tibble(id = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
                     1, 1, 1, 1, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7),
              PM01 = c(NA, -3, NA, -2, -1, 1, 2, NA, NA, -2, -1, NA, -3, -2, -1,
                       1, 2, 3, NA, NA, -2, -1, 1, 2, 3, NA, NA, NA, NA, NA),
              PM02 = c(1, -2, NA, NA, NA, -3, -2, -1, NA, 1, 2, NA, NA, NA, NA,
                       NA, NA, NA, NA, NA, NA, NA, -1, 1, 2, NA, NA, NA, NA, NA),
              PM03 = c(NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,
                       NA, NA, NA, NA, NA, NA, NA, -3, -2, -1, 1, 2, 3, NA, NA)
               );dfa
#> # A tibble: 30 x 4
#>       id  PM01  PM02  PM03
#>    <dbl> <dbl> <dbl> <dbl>
#>  1     0    NA     1    NA
#>  2     0    -3    -2    NA
#>  3     0    NA    NA    NA
#>  4     0    -2    NA    NA
#>  5     0    -1    NA    NA
#>  6     0     1    -3    NA
#>  7     0     2    -2    NA
#>  8     0    NA    -1    NA
#>  9     0    NA    NA    NA
#> 10     0    -2     1    NA
#> # ... with 20 more rows

在此 PM014-7 中将是一个匹配项。

我已经 tidyr::gather 数据太长以至于只有一个向量我必须查看。像这样,

# install.packages(c("tidyverse"), dependencies = TRUE)
library(tidyr)
dfL <- dfa  %>% select(id, PM01:PM03) %>% gather(shift, PM, PM01:PM03, na.rm = FALSE) %>% arrange(id, shift)  %>% group_by(id, shift)

我试着解释我在寻找什么,但发现如果我只是展示我想要的结果可能会更清楚。像这样,

cbind(dfL, TF = c(FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, 
TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, 
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, 
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, 
TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE))
# A tibble: 90 x 4
# Groups:   id, shift [9]
      id shift    PM    TF
   <dbl> <chr> <dbl> <lgl>
 1     0  PM01    NA FALSE
 2     0  PM01    -3 FALSE
 3     0  PM01    NA FALSE
 4     0  PM01    -2 FALSE
 5     0  PM01    -1 FALSE
 6     0  PM01     1 FALSE
 7     0  PM01    NA FALSE
 8     0  PM01    NA FALSE
 9     0  PM01    NA FALSE
10     0  PM01    -2 FALSE
# ... with 80 more rows

不管效率如何,你可能会这样做;从 dfL 开始,创建一个新的组变量来标识连续的 NA 或非 NAs 块,然后通过检查每个块内的条件来添加条件列:

dfL %>% 
    group_by(g = cumsum(is.na(PM) != lag(is.na(PM), default=0)), add=T) %>% 
    mutate(TF = n() >= 4 && all(c(-1,1) %in% PM)) %>% 
    ungroup() %>% select(-g)

# A tibble: 90 x 4
#      id shift    PM    TF
#   <dbl> <chr> <dbl> <lgl>
# 1     0  PM01    NA FALSE
# 2     0  PM01    -3 FALSE
# 3     0  PM01    NA FALSE
# 4     0  PM01    -2  TRUE
# 5     0  PM01    -1  TRUE
# 6     0  PM01     1  TRUE
# 7     0  PM01     2  TRUE
# 8     0  PM01    NA FALSE
# 9     0  PM01    NA FALSE
#10     0  PM01    -2 FALSE
# ... with 80 more rows