2017-10-27 1 views
0

Ich habe ein Panel, dfL, wo ich versuche, Reihe fortlaufende Nummern innerhalb ID, id, und Segment, shift in den Variablen zu identifizieren. Ich suche nach Seriennummern, die die Nummern -1 und 1 enthalten und hat die Länge 4 oder mehr.identifizieren Reihe von fortlaufenden Nummern innerhalb ID und Segment

Unter meiner Darstellung der Situation mit Daten,

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

Ich habe zunächst die Daten im Wide-Format wie diese

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 

In dieser dieser PM01 Reihe 4-7 ein Spiel sein würde.

Ich habe tidyr::gather die Daten zu lang, um nur einen Vektor zu haben, den ich durchsehen muss. Wie diese

# 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) 

habe ich versucht zu erklären, was ich suche, aber fand heraus, es könnte klarer, wenn ich einfach meine gewünschte Ergebnis zeigen. So,

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 

Antwort

1

Unabhängig von der Effizienz, könnten Sie dies tun; Ausgehend von dfL, eine neue Gruppe, die aufeinanderfolgende variable NA oder nicht NA s Chunks identifizieren, und dann die Spalte Bedingung hinzuzufügen, indem die Bedingungen innerhalb der einzelnen Chunk prüft:

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 
Verwandte Themen