Search code examples
rregexdplyrgrepl

Selecting specific sequences from a column of sequences, with a maximum distance in between


I have data as follows:

data <- as.data.frame(c("[0;20;1;2;3;4;5;6;7;22;8;9;10;11;12;13;14;23;17;24;18;25;15;26;16;19]", 
                        "[0;21;16;27;15;28;8;9;10;11;12;13;14;29;1;2;3;4;5;6;7;30;18;31;17;19]", 
                        "[0;20;15;22;16;23;18;24;17;25;1;2;3;4;5;6;7;26;8;9;10;11;12;13;14;19]", 
                        "[0;20;8;9;10;11;12;13;14;22;1;2;3;4;5;6;7;23;15;24;16;25;17;26;18;19]", 
                        "[0;21;18;27;17;28;15;29;16;30;8;9;10;11;12;13;14;31;1;2;3;4;5;6;7;19]", 
                        "[0;20;1;2;3;4;5;6;7;22;8;9;10;11;12;13;14;23;15;24;16;25;17;26;18;19]", 
                        "[0;21;1;2;3;4;5;6;7;27;8;9;10;11;12;13;14;28;17;29;18;30;16;31;15;19]", 
                        "[0;20;8;9;10;11;12;13;14;22;1;2;3;4;5;6;7;23;16;24;15;25;18;26;17;19]", 
                        "[0;21;17;27;18;28;16;29;15;30;8;9;10;11;12;13;14;31;1;2;3;4;5;6;7;19]", 
                        "[0;20;15;22;16;23;18;24;17;25;8;9;10;11;12;13;14;26;1;2;3;4;5;6;7;19]", 
                        "[0;21;18;27;17;28;16;29;15;30;1;2;3;4;5;6;7;31;8;9;10;11;12;13;14;19]", 
                        "[0;20;1;2;3;4;5;6;7;22;8;9;10;11;12;13;14;23;18;24;17;25;16;26;15;19]", 
                        "[0;21;15;27;16;28;1;2;3;4;5;6;7;29;8;9;10;11;12;13;14;30;18;31;17;19]", 
                        "[0;21;1;2;3;4;5;6;7;27;8;9;10;11;12;13;14;28;15;29;16;30;18;31;17;19]", 
                        "[0;20;16;22;15;23;17;24;18;25;1;2;3;4;5;6;7;26;8;9;10;11;12;13;14;19]", 
                        "[0;20;18;22;17;23;15;24;16;25;8;9;10;11;12;13;14;26;1;2;3;4;5;6;7;19]", 
                        "[0;21;15;27;16;28;8;9;10;11;12;13;14;29;1;2;3;4;5;6;7;30;18;31;17;19]", 
                        "[0;21;15;27;16;28;1;2;3;4;5;6;7;29;8;9;10;11;12;13;14;30;17;31;18;19]", 
                        "[0;21;18;27;17;28;15;29;16;30;1;2;3;4;5;6;7;31;8;9;10;11;12;13;14;19]", 
                        "[0;20;16;22;15;23;17;24;18;25;8;9;10;11;12;13;14;26;1;2;3;4;5;6;7;19]", 
                        "[0;21;8;9;10;11;12;13;14;27;1;2;3;4;5;6;7;28;17;29;18;30;16;31;15;19]", 
                        "[0;20;16;22;15;23;18;24;17;25;1;2;3;4;5;6;7;26;8;9;10;11;12;13;14;19]", 
                        "[0;21;8;9;10;11;12;13;14;27;1;2;3;4;5;6;7;28;18;29;17;30;16;31;15;19]", 
                        "[0;20;15;22;16;23;1;2;3;4;5;6;7;24;8;9;10;11;12;13;14;25;18;26;17;19]", 
                        "[0;21;16;27;15;28;18;29;17;30;8;9;10;11;12;13;14;31;1;2;3;4;5;6;7;19]", 
                        "[0;20;15;22;16;23;17;24;18;25;1;2;3;4;5;6;7;26;8;9;10;11;12;13;14;19]"
))

What I wanted to do is add an extra column to the data.frame, which tells me, if the first criteria, the second criteria, both or neither of the following criteria are fulfilled:

  1. Rows for which 17, comes later in the sequence than 15.
  2. Rows for which 18, comes later in the sequence than 16.

In this post, Ronak gave the following, very nice solution:

library(dplyr)

data %>%
  mutate(result = case_when(grepl('15.*17', col) & grepl('16.*18', col) ~ 'Both', 
                            grepl('15.*17', col) ~ 'First', 
                            grepl('16.*18', col) ~ 'Second', 
                            TRUE ~ 'Neither'))

I realised a bit later, that I wanted to slightly change the conditions;

  1. Rows for which 17, comes later in the sequence than 15, but with a maximum of three other numbers in between.
  2. Rows for which 18, comes later in the sequence than 16, but with a maximum of one other number in between.

I have been looking at the regular expressions, but I cannot really figure out how to adapt the pattern. This mostly has to do with the fact that I don't know how many double and single digit numbers there are in between.

I thought for example to do something like /^[.]{0,10}$/ but I do not know how many characters will be in between. Could anyone help?


Solution

  • Is this what you need?

    data %>%
      mutate(result = case_when(grepl('15(;\\d+;){,3}17', seq) & grepl('16(;\\d+;){,1}18', seq) ~ 'Both', 
                                grepl('15(;\\d+;){,3}17', seq) ~ 'First', 
                                grepl('16(;\\d+;){,1}18', seq) ~ 'Second', 
                                TRUE ~ 'Neither'))
        seq  result
    1  [0;20;1;2;3;4;5;6;7;22;8;9;10;11;12;13;14;23;17;24;18;25;15;26;16;19] Neither
    2  [0;21;16;27;15;28;8;9;10;11;12;13;14;29;1;2;3;4;5;6;7;30;18;31;17;19] Neither
    3  [0;20;15;22;16;23;18;24;17;25;1;2;3;4;5;6;7;26;8;9;10;11;12;13;14;19]  Second
    4  [0;20;8;9;10;11;12;13;14;22;1;2;3;4;5;6;7;23;15;24;16;25;17;26;18;19] Neither
    5  [0;21;18;27;17;28;15;29;16;30;8;9;10;11;12;13;14;31;1;2;3;4;5;6;7;19] Neither
    6  [0;20;1;2;3;4;5;6;7;22;8;9;10;11;12;13;14;23;15;24;16;25;17;26;18;19] Neither
    7  [0;21;1;2;3;4;5;6;7;27;8;9;10;11;12;13;14;28;17;29;18;30;16;31;15;19] Neither
    8  [0;20;8;9;10;11;12;13;14;22;1;2;3;4;5;6;7;23;16;24;15;25;18;26;17;19] Neither
    9  [0;21;17;27;18;28;16;29;15;30;8;9;10;11;12;13;14;31;1;2;3;4;5;6;7;19] Neither
    10 [0;20;15;22;16;23;18;24;17;25;8;9;10;11;12;13;14;26;1;2;3;4;5;6;7;19]  Second
    11 [0;21;18;27;17;28;16;29;15;30;1;2;3;4;5;6;7;31;8;9;10;11;12;13;14;19] Neither
    12 [0;20;1;2;3;4;5;6;7;22;8;9;10;11;12;13;14;23;18;24;17;25;16;26;15;19] Neither
    13 [0;21;15;27;16;28;1;2;3;4;5;6;7;29;8;9;10;11;12;13;14;30;18;31;17;19] Neither
    14 [0;21;1;2;3;4;5;6;7;27;8;9;10;11;12;13;14;28;15;29;16;30;18;31;17;19]  Second
    15 [0;20;16;22;15;23;17;24;18;25;1;2;3;4;5;6;7;26;8;9;10;11;12;13;14;19]   First
    16 [0;20;18;22;17;23;15;24;16;25;8;9;10;11;12;13;14;26;1;2;3;4;5;6;7;19] Neither
    17 [0;21;15;27;16;28;8;9;10;11;12;13;14;29;1;2;3;4;5;6;7;30;18;31;17;19] Neither
    18 [0;21;15;27;16;28;1;2;3;4;5;6;7;29;8;9;10;11;12;13;14;30;17;31;18;19] Neither
    19 [0;21;18;27;17;28;15;29;16;30;1;2;3;4;5;6;7;31;8;9;10;11;12;13;14;19] Neither
    20 [0;20;16;22;15;23;17;24;18;25;8;9;10;11;12;13;14;26;1;2;3;4;5;6;7;19]   First
    21 [0;21;8;9;10;11;12;13;14;27;1;2;3;4;5;6;7;28;17;29;18;30;16;31;15;19] Neither
    22 [0;20;16;22;15;23;18;24;17;25;1;2;3;4;5;6;7;26;8;9;10;11;12;13;14;19] Neither
    23 [0;21;8;9;10;11;12;13;14;27;1;2;3;4;5;6;7;28;18;29;17;30;16;31;15;19] Neither
    24 [0;20;15;22;16;23;1;2;3;4;5;6;7;24;8;9;10;11;12;13;14;25;18;26;17;19] Neither
    25 [0;21;16;27;15;28;18;29;17;30;8;9;10;11;12;13;14;31;1;2;3;4;5;6;7;19] Neither
    26 [0;20;15;22;16;23;17;24;18;25;1;2;3;4;5;6;7;26;8;9;10;11;12;13;14;19] Neither