просматривая предыдущие и последующие строки, где условие выполняется группой R - PullRequest
0 голосов
/ 11 октября 2019

Это похоже на вопрос , который я недавно задавал, но отличается. Допустим, у меня есть следующие данные:

library(tidyverse)
    df <- structure(list(x = c("a", "a", "a", "a", "b", "b", "b", "b", 
                               "b", "c", "c", "c", "c", "d", "d", "e", "e", "f", "g", "g", "g", 
                               "g", "g", "g", "g", "g"), y = c(" free", " with", "  sus", "  sus", 
                                                               "  sus", " free", " free", "  sus", " free", " with", " sus", 
                                                               " free", "  sus", " free", " free", " with", "  sus", "  sus", 
                                                               " free", " sus", " sus", " sus", " sus", " free", " sus", " free"
                               ), indicator = c(0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 
                                                0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0)), row.names = c(NA, -26L), class = c("tbl_df", 
                                                                                                                      "tbl", "data.frame"))
    df
       x     y       indicator
       <chr> <chr>       <dbl>
     1 a     " free"         0
     2 a     " with"         0
     3 a     "  sus"         1
     4 a     "  sus"         0
     5 b     "  sus"         1
     6 b     " free"         0
     7 b     " free"         0
     8 b     "  sus"         1
     9 b     " free"         0
    10 c     " with"         0
    11 c     " sus"          1
    12 c     " free"         0
    13 c     "  sus"         1
    14 d     " free"         0
    15 d     " free"         0
    16 e     " with"         0
    17 e     "  sus"         1
    18 f     "  sus"         1
    19 g     " free"         0
    20 g     " sus"          0
    21 g     " sus"          1
    22 g     " sus"          0
    23 g     " sus"          0
    24 g     " free"         0
    25 g     " sus"          1
    26 g     " free"         0

Я хочу создать переменную, где, если indicator==1, я ищу предыдущие и последующие строки, группируя переменную x и присваиваю ей значение, равное 1, еслиследующее и предыдущее вхождение, которое не sus, равно free. Итак, если theres a with перед следующим или последним free, тогда он не получит значение 1. Если indicator==1 и он находится в последнем или первом ряду группы, то я предполагаю with отсутствует в следующей или предыдущей строке, например, группа b, c, e. Мой желаемый вывод:

   x     y       indicator newvariable
   <chr> <chr>       <dbl>       <dbl>
 1 a     " free"         0           0
 2 a     " with"         0           0
 3 a     "  sus"         1           0
 4 a     "  sus"         0           0
 5 b     "  sus"         1           1
 6 b     " free"         0           0
 7 b     " free"         0           0
 8 b     "  sus"         1           1
 9 b     " free"         0           0
10 c     " with"         0           0
11 c     " sus"          1           0
12 c     " free"         0           0
13 c     "  sus"         1           1
14 d     " free"         0           0
15 d     " free"         0           0
16 e     " with"         0           0
17 e     "  sus"         1           0
18 f     "  sus"         1           1
19 g     " free"         0           0
20 g     " sus"          0           0
21 g     " sus"          1           1
22 g     " sus"          0           0
23 g     " sus"          0           0
24 g     " free"         0           0
25 g     " sus"          1           1
26 g     " free"         0           0

Я хочу что-то гибкое, которое может циклически проходить через множество строк (может быть много sus перед free и может быть несколько indicator==1 на группу, как в группеg). Что-то вроде следующего - это то, о чем я думал, но я хочу, чтобы lag и lead просматривали многие предыдущие и последующие строки:

df %>% 
 group_by(x) %>% 
  mutate(newvariable = as.integer(indicator == 1 & lag(y[y != "sus"]) =='free' & lead(y[y != "sus"]) == 'free' ))
    #taken idea from previous question
    #mutate(newvariable = as.integer(last(y) == 'sus' & last(y[y != "sus"]) == 'with')

Я не думаю, что могу сделать такой же подход, какмой последний вопрос к last, но, если у кого-нибудь есть идеи, ищите что-нибудь подобное, пожалуйста? Может быть pmap?

1 Ответ

1 голос
/ 11 октября 2019

Это похоже на работу. Хитрость, которую я использовал, заключается в создании временного фрейма данных, в котором последовательности последовательных идентичных значений y объединены в одну запись.

df = df %>% 
    group_by(x) %>% 
    do({
        # subgroup is constant in series of records with constant x and y
        df_x = mutate(., i=row_number(), subgroup=cumsum(y!=lag(y, default="")))

        df_subgroups = df_x %>% 
            distinct(subgroup, y) %>% 
            mutate(
                prev_distinct_y = lag(y, default="free"),
                next_distinct_y = lead(y, default="free")
            )
        df_x = df_x %>% left_join(df_subgroups)
        df_x %>% mutate(fixed_indicator = 0 + (indicator==1 & prev_distinct_y!=" with" & next_distinct_y!=" with") )
    })
...