Search code examples
rlagdplyr

Use the results of previous row to mutate in a specific numeric order


I want to insert a specific numeric order based on the value of the previous row. Here's the dataset

 gspoi
1   FALSE
2   FALSE
3   FALSE
4   FALSE
5   FALSE
6   FALSE
7   FALSE
8   FALSE
9   FALSE
10  FALSE
11  FALSE
12  FALSE
13   TRUE
14   TRUE
15   TRUE
16   TRUE
17   TRUE
18   TRUE
19   TRUE
20   TRUE
21   TRUE
22   TRUE
23   TRUE
24   TRUE
25  FALSE
26  FALSE
27  FALSE
28  FALSE
29  FALSE
30  FALSE
31  FALSE
32  FALSE
33  FALSE
34   TRUE
35   TRUE
36   TRUE
37   TRUE
38   TRUE
39   TRUE
40   TRUE
41   TRUE
42   TRUE
43   TRUE
44  FALSE
45  FALSE
46  FALSE
47  FALSE
48  FALSE
49  FALSE
50  FALSE
51  FALSE
52  FALSE
53   TRUE

And here is the order I would like to insert at the present time. The sequence should be inserted based on the result of the previous row.

c(6,12,9,11,2,10)

The outcome should look like this:

 gspoi TreatB
1   FALSE 6
2   FALSE 6
3   FALSE 6
4   FALSE 6
5   FALSE 6
6   FALSE 6
7   FALSE 6
8   FALSE 6
9   FALSE 6
10  FALSE 6
11  FALSE 6
12  FALSE 6
13   TRUE 12
14   TRUE 12
15   TRUE 12
16   TRUE 12
17   TRUE 12
18   TRUE 12
19   TRUE 12
20   TRUE 12
21   TRUE 12 
22   TRUE 12
23   TRUE 12
24   TRUE 12 
25  FALSE 9
26  FALSE 9
27  FALSE 9
28  FALSE 9
29  FALSE 9
30  FALSE 9
31  FALSE 9
32  FALSE 9
33  FALSE 9
34   TRUE 11
35   TRUE 11
36   TRUE 11
37   TRUE 11
38   TRUE 11
39   TRUE 11
40   TRUE 11
41   TRUE 11
42   TRUE 11 
43   TRUE 11
44  FALSE 2
45  FALSE 2
46  FALSE 2
47  FALSE 2
48  FALSE 2
49  FALSE 2
50  FALSE 2
51  FALSE 2
52  FALSE 2
53 TRUE 10

It is known that that FALSE and TRUE may not appear the same number of times. I've tried to use if_else but it didn't work for me. Would someone be able to help me?


Solution

  • Using the tidyverse packages (specifically dplyr and tidyr)

    library(tidyverse)
    
    TreatB <- c(6,12,9,11,2,10)
    
    df <- df %>% 
      mutate(Treat = case_when(lag(value, default = TRUE) != value ~ "New",
                               TRUE ~ "Same"))
    
    df$TreatB[df$Treat == "New"] <- TreatB
    
    df <- df %>%
      tidyr::fill(TreatB, .direction = c("down")) %>%
      mutate(Treat = NULL)
    # A tibble: 53 x 3
         row value TreatB
       <dbl> <lgl>  <dbl>
     1     1 FALSE      6
     2     2 FALSE      6
     3     3 FALSE      6
     4     4 FALSE      6
     5     5 FALSE      6
     6     6 FALSE      6
     7     7 FALSE      6
     8     8 FALSE      6
     9     9 FALSE      6
    10    10 FALSE      6
    11    11 FALSE      6
    12    12 FALSE      6
    13    13 TRUE      12
    14    14 TRUE      12
    15    15 TRUE      12
    16    16 TRUE      12
    17    17 TRUE      12
    18    18 TRUE      12
    19    19 TRUE      12
    20    20 TRUE      12
    21    21 TRUE      12
    22    22 TRUE      12
    23    23 TRUE      12
    24    24 TRUE      12
    25    25 FALSE      9
    26    26 FALSE      9
    27    27 FALSE      9
    28    28 FALSE      9
    29    29 FALSE      9
    30    30 FALSE      9
    31    31 FALSE      9
    32    32 FALSE      9
    33    33 FALSE      9
    34    34 TRUE      11
    35    35 TRUE      11
    36    36 TRUE      11
    37    37 TRUE      11
    38    38 TRUE      11
    39    39 TRUE      11
    40    40 TRUE      11
    41    41 TRUE      11
    42    42 TRUE      11
    43    43 TRUE      11
    44    44 FALSE      2
    45    45 FALSE      2
    46    46 FALSE      2
    47    47 FALSE      2
    48    48 FALSE      2
    49    49 FALSE      2
    50    50 FALSE      2
    51    51 FALSE      2
    52    52 FALSE      2
    53    53 TRUE      10