Rank groups within a grouped sequence of TRUE/FALSE and NA The 2019 Stack Overflow Developer Survey Results Are InGrouping functions (tapply, by, aggregate) and the *apply familyCharacters counting and subletting specific patternsdata.table vs dplyr: can one do something well the other can't or does poorly?how to make a bar plot for a list of dataframes?How to group by unique values in a list in RUsing Group by in R using dplyrPandas - Alternative to rank() function that gives unique ordinal ranks for a columnRank within group in for loop in RFilter two tables with crosstalkGetting map from purrr to work with paste0

I see my dog run

Could a US political party gain complete control over the government by removing checks & balances?

Why do some words that are not inflected have an umlaut?

What is the steepest angle that a canal can be traversable without locks?

Are there any other methods to apply to solving simultaneous equations?

Unbreakable Formation vs. Cry of the Carnarium

Understanding the implication of what "well-defined" means for the operation in quotient group

How can I make payments on the Internet without leaving a money trail?

Is bread bad for ducks?

What does "sndry explns" mean in one of the Hitchhiker's guide books?

Realistic Alternatives to Dust: What Else Could Feed a Plankton Bloom?

How can I fix this gap between bookcases I made?

Rank groups within a grouped sequence of TRUE/FALSE and NA

What are the motivations for publishing new editions of an existing textbook, beyond new discoveries in a field?

How to manage monthly salary

What could be the right powersource for 15 seconds lifespan disposable giant chainsaw?

How are circuits which use complex ICs normally simulated?

Should I use my personal or workplace e-mail when registering to external websites for work purpose?

When to use the root test. Is this not a good situation to use it?

How come people say “Would of”?

Inflated grade on resume at previous job, might former employer tell new employer?

Why is Grand Jury testimony secret?

Does a dangling wire really electrocute me if I'm standing in water?

A poker game description that does not feel gimmicky



Rank groups within a grouped sequence of TRUE/FALSE and NA



The 2019 Stack Overflow Developer Survey Results Are InGrouping functions (tapply, by, aggregate) and the *apply familyCharacters counting and subletting specific patternsdata.table vs dplyr: can one do something well the other can't or does poorly?how to make a bar plot for a list of dataframes?How to group by unique values in a list in RUsing Group by in R using dplyrPandas - Alternative to rank() function that gives unique ordinal ranks for a columnRank within group in for loop in RFilter two tables with crosstalkGetting map from purrr to work with paste0



.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;








7















I have a little nut to crack.



I have a data.frame like this:



 group criterium
1 A NA
2 A TRUE
3 A TRUE
4 A TRUE
5 A FALSE
6 A FALSE
7 A TRUE
8 A TRUE
9 A FALSE
10 A TRUE
11 A TRUE
12 A TRUE
13 B NA
14 B FALSE
15 B TRUE
16 B TRUE
17 B TRUE
18 B FALSE

structure(list(group = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L,
1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L), .Label = c("A",
"B"), class = "factor"), criterium = c(NA, TRUE, TRUE, TRUE,
FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, NA, FALSE,
TRUE, TRUE, TRUE, FALSE)), class = "data.frame", row.names = c(NA,
-18L))



And I want to rank the groups of TRUE in column criterium in ascending order while disregarding the FALSEand NA. The goal is to have a unique group identifier inside each group of group.



So the result should look like:



 group criterium goal
1 A NA NA
2 A TRUE 1
3 A TRUE 1
4 A TRUE 1
5 A FALSE NA
6 A FALSE NA
7 A TRUE 2
8 A TRUE 2
9 A FALSE NA
10 A TRUE 3
11 A TRUE 3
12 A TRUE 3
13 B NA NA
14 B FALSE NA
15 B TRUE 1
16 B TRUE 1
17 B TRUE 1
18 B FALSE NA



I'm sure there is a relatively easy way to do this, I just can't think of one. I experimented with dense_rank() and other window functions of dplyr, but to no avail.



Thanks for the help!










share|improve this question






























    7















    I have a little nut to crack.



    I have a data.frame like this:



     group criterium
    1 A NA
    2 A TRUE
    3 A TRUE
    4 A TRUE
    5 A FALSE
    6 A FALSE
    7 A TRUE
    8 A TRUE
    9 A FALSE
    10 A TRUE
    11 A TRUE
    12 A TRUE
    13 B NA
    14 B FALSE
    15 B TRUE
    16 B TRUE
    17 B TRUE
    18 B FALSE

    structure(list(group = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L,
    1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L), .Label = c("A",
    "B"), class = "factor"), criterium = c(NA, TRUE, TRUE, TRUE,
    FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, NA, FALSE,
    TRUE, TRUE, TRUE, FALSE)), class = "data.frame", row.names = c(NA,
    -18L))



    And I want to rank the groups of TRUE in column criterium in ascending order while disregarding the FALSEand NA. The goal is to have a unique group identifier inside each group of group.



    So the result should look like:



     group criterium goal
    1 A NA NA
    2 A TRUE 1
    3 A TRUE 1
    4 A TRUE 1
    5 A FALSE NA
    6 A FALSE NA
    7 A TRUE 2
    8 A TRUE 2
    9 A FALSE NA
    10 A TRUE 3
    11 A TRUE 3
    12 A TRUE 3
    13 B NA NA
    14 B FALSE NA
    15 B TRUE 1
    16 B TRUE 1
    17 B TRUE 1
    18 B FALSE NA



    I'm sure there is a relatively easy way to do this, I just can't think of one. I experimented with dense_rank() and other window functions of dplyr, but to no avail.



    Thanks for the help!










    share|improve this question


























      7












      7








      7








      I have a little nut to crack.



      I have a data.frame like this:



       group criterium
      1 A NA
      2 A TRUE
      3 A TRUE
      4 A TRUE
      5 A FALSE
      6 A FALSE
      7 A TRUE
      8 A TRUE
      9 A FALSE
      10 A TRUE
      11 A TRUE
      12 A TRUE
      13 B NA
      14 B FALSE
      15 B TRUE
      16 B TRUE
      17 B TRUE
      18 B FALSE

      structure(list(group = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L,
      1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L), .Label = c("A",
      "B"), class = "factor"), criterium = c(NA, TRUE, TRUE, TRUE,
      FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, NA, FALSE,
      TRUE, TRUE, TRUE, FALSE)), class = "data.frame", row.names = c(NA,
      -18L))



      And I want to rank the groups of TRUE in column criterium in ascending order while disregarding the FALSEand NA. The goal is to have a unique group identifier inside each group of group.



      So the result should look like:



       group criterium goal
      1 A NA NA
      2 A TRUE 1
      3 A TRUE 1
      4 A TRUE 1
      5 A FALSE NA
      6 A FALSE NA
      7 A TRUE 2
      8 A TRUE 2
      9 A FALSE NA
      10 A TRUE 3
      11 A TRUE 3
      12 A TRUE 3
      13 B NA NA
      14 B FALSE NA
      15 B TRUE 1
      16 B TRUE 1
      17 B TRUE 1
      18 B FALSE NA



      I'm sure there is a relatively easy way to do this, I just can't think of one. I experimented with dense_rank() and other window functions of dplyr, but to no avail.



      Thanks for the help!










      share|improve this question
















      I have a little nut to crack.



      I have a data.frame like this:



       group criterium
      1 A NA
      2 A TRUE
      3 A TRUE
      4 A TRUE
      5 A FALSE
      6 A FALSE
      7 A TRUE
      8 A TRUE
      9 A FALSE
      10 A TRUE
      11 A TRUE
      12 A TRUE
      13 B NA
      14 B FALSE
      15 B TRUE
      16 B TRUE
      17 B TRUE
      18 B FALSE

      structure(list(group = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L,
      1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L), .Label = c("A",
      "B"), class = "factor"), criterium = c(NA, TRUE, TRUE, TRUE,
      FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, NA, FALSE,
      TRUE, TRUE, TRUE, FALSE)), class = "data.frame", row.names = c(NA,
      -18L))



      And I want to rank the groups of TRUE in column criterium in ascending order while disregarding the FALSEand NA. The goal is to have a unique group identifier inside each group of group.



      So the result should look like:



       group criterium goal
      1 A NA NA
      2 A TRUE 1
      3 A TRUE 1
      4 A TRUE 1
      5 A FALSE NA
      6 A FALSE NA
      7 A TRUE 2
      8 A TRUE 2
      9 A FALSE NA
      10 A TRUE 3
      11 A TRUE 3
      12 A TRUE 3
      13 B NA NA
      14 B FALSE NA
      15 B TRUE 1
      16 B TRUE 1
      17 B TRUE 1
      18 B FALSE NA



      I'm sure there is a relatively easy way to do this, I just can't think of one. I experimented with dense_rank() and other window functions of dplyr, but to no avail.



      Thanks for the help!







      r dplyr rank






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited 56 mins ago







      Humpelstielzchen

















      asked 1 hour ago









      HumpelstielzchenHumpelstielzchen

      1,3401316




      1,3401316






















          4 Answers
          4






          active

          oldest

          votes


















          3














          Maybe I have over-complicated this but one way with dplyr is



          library(dplyr)

          df %>%
          mutate(temp = replace(criterium, is.na(criterium), FALSE),
          temp1 = cumsum(!temp)) %>%
          group_by(temp1) %>%
          mutate(goal = +(row_number() == which.max(temp) & any(temp))) %>%
          group_by(group) %>%
          mutate(goal = ifelse(temp, cumsum(goal), NA)) %>%
          select(-temp, -temp1)

          # group criterium goal
          # <fct> <lgl> <int>
          # 1 A NA NA
          # 2 A TRUE 1
          # 3 A TRUE 1
          # 4 A TRUE 1
          # 5 A FALSE NA
          # 6 A FALSE NA
          # 7 A TRUE 2
          # 8 A TRUE 2
          # 9 A FALSE NA
          #10 A TRUE 3
          #11 A TRUE 3
          #12 A TRUE 3
          #13 B NA NA
          #14 B FALSE NA
          #15 B TRUE 1
          #16 B TRUE 1
          #17 B TRUE 1
          #18 B FALSE NA


          We first replace NAs in criterium column to FALSE and take cumulative sum over the negation of it (temp1). We group_by temp1 and assign 1 to every first TRUE value in the group. Finally grouping by group we take a cumulative sum for TRUE values or return NA for FALSE and NA values.






          share|improve this answer






























            2














            We can create a custom function via rle, and use it per group, i.e.



            f1 <- function(x) 
            x[is.na(x)] <- FALSE
            rle1 <- rle(x)
            y <- rle1$values
            rle1$values[!y] <- 0
            rle1$values[y] <- cumsum(rle1$values[y])
            return(inverse.rle(rle1))



            do.call(rbind,
            lapply(split(df, df$group), function(i)!i$criterium, NA);
            i))


            Of course, If you want you can apply it via dplyr, i.e.



            library(dplyr)

            df %>%
            group_by(group) %>%
            mutate(goal = f1(criterium),
            goal = replace(goal, is.na(criterium)|!criterium, NA))


            which gives,




            # A tibble: 18 x 3
            # Groups: group [2]
            group criterium goal
            <fct> <lgl> <dbl>
            1 A NA NA
            2 A TRUE 1
            3 A TRUE 1
            4 A TRUE 1
            5 A FALSE NA
            6 A FALSE NA
            7 A TRUE 2
            8 A TRUE 2
            9 A FALSE NA
            10 A TRUE 3
            11 A TRUE 3
            12 A TRUE 3
            13 B NA NA
            14 B FALSE NA
            15 B TRUE 1
            16 B TRUE 1
            17 B TRUE 1
            18 B FALSE NA






            share|improve this answer
































              1














              A different dplyr possibility using rle() and dense_rank() could be:



              df %>%
              group_by(group) %>%
              mutate(rleid = with(rle(criterium), rep(seq_along(lengths), lengths))) %>%
              group_by(group, criterium) %>%
              mutate(res = dense_rank(rleid)) %>%
              ungroup() %>%
              mutate(res = ifelse(criterium, res, NA)) %>%
              select(-rleid)

              group criterium res
              <fct> <lgl> <int>
              1 A NA NA
              2 A TRUE 1
              3 A TRUE 1
              4 A TRUE 1
              5 A FALSE NA
              6 A FALSE NA
              7 A TRUE 2
              8 A TRUE 2
              9 A FALSE NA
              10 A TRUE 3
              11 A TRUE 3
              12 A TRUE 3
              13 B NA NA
              14 B FALSE NA
              15 B TRUE 1
              16 B TRUE 1
              17 B TRUE 1
              18 B FALSE NA





              share|improve this answer






























                1














                A data.table option using rle



                library(data.table)
                DT <- as.data.table(dat)
                DT[, goal :=
                r <- rle(replace(criterium, is.na(criterium), FALSE))
                r$values <- with(r, cumsum(values) * values)
                out <- inverse.rle(r)
                replace(out, out == 0, NA)
                , by = group]
                DT
                # group criterium goal
                # 1: A NA NA
                # 2: A TRUE 1
                # 3: A TRUE 1
                # 4: A TRUE 1
                # 5: A FALSE NA
                # 6: A FALSE NA
                # 7: A TRUE 2
                # 8: A TRUE 2
                # 9: A FALSE NA
                #10: A TRUE 3
                #11: A TRUE 3
                #12: A TRUE 3
                #13: B NA NA
                #14: B FALSE NA
                #15: B TRUE 1
                #16: B TRUE 1
                #17: B TRUE 1
                #18: B FALSE NA


                data



                dat <- structure(list(group = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 
                1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L), .Label = c("A",
                "B"), class = "factor"), criterium = c(NA, TRUE, TRUE, TRUE,
                FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, NA, FALSE,
                TRUE, TRUE, TRUE, FALSE)), class = "data.frame", row.names = c(NA,
                -18L))





                share|improve this answer

























                • Wow, impressive. Thanks for introducing me to rleand inverse.rle. Gruß nach Leipzig.

                  – Humpelstielzchen
                  20 mins ago











                • @Humpelstielzchen Gern geschehen. Will try to simplify and explain the logic a bit.

                  – markus
                  16 mins ago












                Your Answer






                StackExchange.ifUsing("editor", function ()
                StackExchange.using("externalEditor", function ()
                StackExchange.using("snippets", function ()
                StackExchange.snippets.init();
                );
                );
                , "code-snippets");

                StackExchange.ready(function()
                var channelOptions =
                tags: "".split(" "),
                id: "1"
                ;
                initTagRenderer("".split(" "), "".split(" "), channelOptions);

                StackExchange.using("externalEditor", function()
                // Have to fire editor after snippets, if snippets enabled
                if (StackExchange.settings.snippets.snippetsEnabled)
                StackExchange.using("snippets", function()
                createEditor();
                );

                else
                createEditor();

                );

                function createEditor()
                StackExchange.prepareEditor(
                heartbeatType: 'answer',
                autoActivateHeartbeat: false,
                convertImagesToLinks: true,
                noModals: true,
                showLowRepImageUploadWarning: true,
                reputationToPostImages: 10,
                bindNavPrevention: true,
                postfix: "",
                imageUploader:
                brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
                contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
                allowUrls: true
                ,
                onDemand: true,
                discardSelector: ".discard-answer"
                ,immediatelyShowMarkdownHelp:true
                );



                );













                draft saved

                draft discarded


















                StackExchange.ready(
                function ()
                StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55606323%2frank-groups-within-a-grouped-sequence-of-true-false-and-na%23new-answer', 'question_page');

                );

                Post as a guest















                Required, but never shown

























                4 Answers
                4






                active

                oldest

                votes








                4 Answers
                4






                active

                oldest

                votes









                active

                oldest

                votes






                active

                oldest

                votes









                3














                Maybe I have over-complicated this but one way with dplyr is



                library(dplyr)

                df %>%
                mutate(temp = replace(criterium, is.na(criterium), FALSE),
                temp1 = cumsum(!temp)) %>%
                group_by(temp1) %>%
                mutate(goal = +(row_number() == which.max(temp) & any(temp))) %>%
                group_by(group) %>%
                mutate(goal = ifelse(temp, cumsum(goal), NA)) %>%
                select(-temp, -temp1)

                # group criterium goal
                # <fct> <lgl> <int>
                # 1 A NA NA
                # 2 A TRUE 1
                # 3 A TRUE 1
                # 4 A TRUE 1
                # 5 A FALSE NA
                # 6 A FALSE NA
                # 7 A TRUE 2
                # 8 A TRUE 2
                # 9 A FALSE NA
                #10 A TRUE 3
                #11 A TRUE 3
                #12 A TRUE 3
                #13 B NA NA
                #14 B FALSE NA
                #15 B TRUE 1
                #16 B TRUE 1
                #17 B TRUE 1
                #18 B FALSE NA


                We first replace NAs in criterium column to FALSE and take cumulative sum over the negation of it (temp1). We group_by temp1 and assign 1 to every first TRUE value in the group. Finally grouping by group we take a cumulative sum for TRUE values or return NA for FALSE and NA values.






                share|improve this answer



























                  3














                  Maybe I have over-complicated this but one way with dplyr is



                  library(dplyr)

                  df %>%
                  mutate(temp = replace(criterium, is.na(criterium), FALSE),
                  temp1 = cumsum(!temp)) %>%
                  group_by(temp1) %>%
                  mutate(goal = +(row_number() == which.max(temp) & any(temp))) %>%
                  group_by(group) %>%
                  mutate(goal = ifelse(temp, cumsum(goal), NA)) %>%
                  select(-temp, -temp1)

                  # group criterium goal
                  # <fct> <lgl> <int>
                  # 1 A NA NA
                  # 2 A TRUE 1
                  # 3 A TRUE 1
                  # 4 A TRUE 1
                  # 5 A FALSE NA
                  # 6 A FALSE NA
                  # 7 A TRUE 2
                  # 8 A TRUE 2
                  # 9 A FALSE NA
                  #10 A TRUE 3
                  #11 A TRUE 3
                  #12 A TRUE 3
                  #13 B NA NA
                  #14 B FALSE NA
                  #15 B TRUE 1
                  #16 B TRUE 1
                  #17 B TRUE 1
                  #18 B FALSE NA


                  We first replace NAs in criterium column to FALSE and take cumulative sum over the negation of it (temp1). We group_by temp1 and assign 1 to every first TRUE value in the group. Finally grouping by group we take a cumulative sum for TRUE values or return NA for FALSE and NA values.






                  share|improve this answer

























                    3












                    3








                    3







                    Maybe I have over-complicated this but one way with dplyr is



                    library(dplyr)

                    df %>%
                    mutate(temp = replace(criterium, is.na(criterium), FALSE),
                    temp1 = cumsum(!temp)) %>%
                    group_by(temp1) %>%
                    mutate(goal = +(row_number() == which.max(temp) & any(temp))) %>%
                    group_by(group) %>%
                    mutate(goal = ifelse(temp, cumsum(goal), NA)) %>%
                    select(-temp, -temp1)

                    # group criterium goal
                    # <fct> <lgl> <int>
                    # 1 A NA NA
                    # 2 A TRUE 1
                    # 3 A TRUE 1
                    # 4 A TRUE 1
                    # 5 A FALSE NA
                    # 6 A FALSE NA
                    # 7 A TRUE 2
                    # 8 A TRUE 2
                    # 9 A FALSE NA
                    #10 A TRUE 3
                    #11 A TRUE 3
                    #12 A TRUE 3
                    #13 B NA NA
                    #14 B FALSE NA
                    #15 B TRUE 1
                    #16 B TRUE 1
                    #17 B TRUE 1
                    #18 B FALSE NA


                    We first replace NAs in criterium column to FALSE and take cumulative sum over the negation of it (temp1). We group_by temp1 and assign 1 to every first TRUE value in the group. Finally grouping by group we take a cumulative sum for TRUE values or return NA for FALSE and NA values.






                    share|improve this answer













                    Maybe I have over-complicated this but one way with dplyr is



                    library(dplyr)

                    df %>%
                    mutate(temp = replace(criterium, is.na(criterium), FALSE),
                    temp1 = cumsum(!temp)) %>%
                    group_by(temp1) %>%
                    mutate(goal = +(row_number() == which.max(temp) & any(temp))) %>%
                    group_by(group) %>%
                    mutate(goal = ifelse(temp, cumsum(goal), NA)) %>%
                    select(-temp, -temp1)

                    # group criterium goal
                    # <fct> <lgl> <int>
                    # 1 A NA NA
                    # 2 A TRUE 1
                    # 3 A TRUE 1
                    # 4 A TRUE 1
                    # 5 A FALSE NA
                    # 6 A FALSE NA
                    # 7 A TRUE 2
                    # 8 A TRUE 2
                    # 9 A FALSE NA
                    #10 A TRUE 3
                    #11 A TRUE 3
                    #12 A TRUE 3
                    #13 B NA NA
                    #14 B FALSE NA
                    #15 B TRUE 1
                    #16 B TRUE 1
                    #17 B TRUE 1
                    #18 B FALSE NA


                    We first replace NAs in criterium column to FALSE and take cumulative sum over the negation of it (temp1). We group_by temp1 and assign 1 to every first TRUE value in the group. Finally grouping by group we take a cumulative sum for TRUE values or return NA for FALSE and NA values.







                    share|improve this answer












                    share|improve this answer



                    share|improve this answer










                    answered 54 mins ago









                    Ronak ShahRonak Shah

                    45.9k104268




                    45.9k104268























                        2














                        We can create a custom function via rle, and use it per group, i.e.



                        f1 <- function(x) 
                        x[is.na(x)] <- FALSE
                        rle1 <- rle(x)
                        y <- rle1$values
                        rle1$values[!y] <- 0
                        rle1$values[y] <- cumsum(rle1$values[y])
                        return(inverse.rle(rle1))



                        do.call(rbind,
                        lapply(split(df, df$group), function(i)!i$criterium, NA);
                        i))


                        Of course, If you want you can apply it via dplyr, i.e.



                        library(dplyr)

                        df %>%
                        group_by(group) %>%
                        mutate(goal = f1(criterium),
                        goal = replace(goal, is.na(criterium)|!criterium, NA))


                        which gives,




                        # A tibble: 18 x 3
                        # Groups: group [2]
                        group criterium goal
                        <fct> <lgl> <dbl>
                        1 A NA NA
                        2 A TRUE 1
                        3 A TRUE 1
                        4 A TRUE 1
                        5 A FALSE NA
                        6 A FALSE NA
                        7 A TRUE 2
                        8 A TRUE 2
                        9 A FALSE NA
                        10 A TRUE 3
                        11 A TRUE 3
                        12 A TRUE 3
                        13 B NA NA
                        14 B FALSE NA
                        15 B TRUE 1
                        16 B TRUE 1
                        17 B TRUE 1
                        18 B FALSE NA






                        share|improve this answer





























                          2














                          We can create a custom function via rle, and use it per group, i.e.



                          f1 <- function(x) 
                          x[is.na(x)] <- FALSE
                          rle1 <- rle(x)
                          y <- rle1$values
                          rle1$values[!y] <- 0
                          rle1$values[y] <- cumsum(rle1$values[y])
                          return(inverse.rle(rle1))



                          do.call(rbind,
                          lapply(split(df, df$group), function(i)!i$criterium, NA);
                          i))


                          Of course, If you want you can apply it via dplyr, i.e.



                          library(dplyr)

                          df %>%
                          group_by(group) %>%
                          mutate(goal = f1(criterium),
                          goal = replace(goal, is.na(criterium)|!criterium, NA))


                          which gives,




                          # A tibble: 18 x 3
                          # Groups: group [2]
                          group criterium goal
                          <fct> <lgl> <dbl>
                          1 A NA NA
                          2 A TRUE 1
                          3 A TRUE 1
                          4 A TRUE 1
                          5 A FALSE NA
                          6 A FALSE NA
                          7 A TRUE 2
                          8 A TRUE 2
                          9 A FALSE NA
                          10 A TRUE 3
                          11 A TRUE 3
                          12 A TRUE 3
                          13 B NA NA
                          14 B FALSE NA
                          15 B TRUE 1
                          16 B TRUE 1
                          17 B TRUE 1
                          18 B FALSE NA






                          share|improve this answer



























                            2












                            2








                            2







                            We can create a custom function via rle, and use it per group, i.e.



                            f1 <- function(x) 
                            x[is.na(x)] <- FALSE
                            rle1 <- rle(x)
                            y <- rle1$values
                            rle1$values[!y] <- 0
                            rle1$values[y] <- cumsum(rle1$values[y])
                            return(inverse.rle(rle1))



                            do.call(rbind,
                            lapply(split(df, df$group), function(i)!i$criterium, NA);
                            i))


                            Of course, If you want you can apply it via dplyr, i.e.



                            library(dplyr)

                            df %>%
                            group_by(group) %>%
                            mutate(goal = f1(criterium),
                            goal = replace(goal, is.na(criterium)|!criterium, NA))


                            which gives,




                            # A tibble: 18 x 3
                            # Groups: group [2]
                            group criterium goal
                            <fct> <lgl> <dbl>
                            1 A NA NA
                            2 A TRUE 1
                            3 A TRUE 1
                            4 A TRUE 1
                            5 A FALSE NA
                            6 A FALSE NA
                            7 A TRUE 2
                            8 A TRUE 2
                            9 A FALSE NA
                            10 A TRUE 3
                            11 A TRUE 3
                            12 A TRUE 3
                            13 B NA NA
                            14 B FALSE NA
                            15 B TRUE 1
                            16 B TRUE 1
                            17 B TRUE 1
                            18 B FALSE NA






                            share|improve this answer















                            We can create a custom function via rle, and use it per group, i.e.



                            f1 <- function(x) 
                            x[is.na(x)] <- FALSE
                            rle1 <- rle(x)
                            y <- rle1$values
                            rle1$values[!y] <- 0
                            rle1$values[y] <- cumsum(rle1$values[y])
                            return(inverse.rle(rle1))



                            do.call(rbind,
                            lapply(split(df, df$group), function(i)!i$criterium, NA);
                            i))


                            Of course, If you want you can apply it via dplyr, i.e.



                            library(dplyr)

                            df %>%
                            group_by(group) %>%
                            mutate(goal = f1(criterium),
                            goal = replace(goal, is.na(criterium)|!criterium, NA))


                            which gives,




                            # A tibble: 18 x 3
                            # Groups: group [2]
                            group criterium goal
                            <fct> <lgl> <dbl>
                            1 A NA NA
                            2 A TRUE 1
                            3 A TRUE 1
                            4 A TRUE 1
                            5 A FALSE NA
                            6 A FALSE NA
                            7 A TRUE 2
                            8 A TRUE 2
                            9 A FALSE NA
                            10 A TRUE 3
                            11 A TRUE 3
                            12 A TRUE 3
                            13 B NA NA
                            14 B FALSE NA
                            15 B TRUE 1
                            16 B TRUE 1
                            17 B TRUE 1
                            18 B FALSE NA







                            share|improve this answer














                            share|improve this answer



                            share|improve this answer








                            edited 28 mins ago

























                            answered 49 mins ago









                            SotosSotos

                            31.3k51741




                            31.3k51741





















                                1














                                A different dplyr possibility using rle() and dense_rank() could be:



                                df %>%
                                group_by(group) %>%
                                mutate(rleid = with(rle(criterium), rep(seq_along(lengths), lengths))) %>%
                                group_by(group, criterium) %>%
                                mutate(res = dense_rank(rleid)) %>%
                                ungroup() %>%
                                mutate(res = ifelse(criterium, res, NA)) %>%
                                select(-rleid)

                                group criterium res
                                <fct> <lgl> <int>
                                1 A NA NA
                                2 A TRUE 1
                                3 A TRUE 1
                                4 A TRUE 1
                                5 A FALSE NA
                                6 A FALSE NA
                                7 A TRUE 2
                                8 A TRUE 2
                                9 A FALSE NA
                                10 A TRUE 3
                                11 A TRUE 3
                                12 A TRUE 3
                                13 B NA NA
                                14 B FALSE NA
                                15 B TRUE 1
                                16 B TRUE 1
                                17 B TRUE 1
                                18 B FALSE NA





                                share|improve this answer



























                                  1














                                  A different dplyr possibility using rle() and dense_rank() could be:



                                  df %>%
                                  group_by(group) %>%
                                  mutate(rleid = with(rle(criterium), rep(seq_along(lengths), lengths))) %>%
                                  group_by(group, criterium) %>%
                                  mutate(res = dense_rank(rleid)) %>%
                                  ungroup() %>%
                                  mutate(res = ifelse(criterium, res, NA)) %>%
                                  select(-rleid)

                                  group criterium res
                                  <fct> <lgl> <int>
                                  1 A NA NA
                                  2 A TRUE 1
                                  3 A TRUE 1
                                  4 A TRUE 1
                                  5 A FALSE NA
                                  6 A FALSE NA
                                  7 A TRUE 2
                                  8 A TRUE 2
                                  9 A FALSE NA
                                  10 A TRUE 3
                                  11 A TRUE 3
                                  12 A TRUE 3
                                  13 B NA NA
                                  14 B FALSE NA
                                  15 B TRUE 1
                                  16 B TRUE 1
                                  17 B TRUE 1
                                  18 B FALSE NA





                                  share|improve this answer

























                                    1












                                    1








                                    1







                                    A different dplyr possibility using rle() and dense_rank() could be:



                                    df %>%
                                    group_by(group) %>%
                                    mutate(rleid = with(rle(criterium), rep(seq_along(lengths), lengths))) %>%
                                    group_by(group, criterium) %>%
                                    mutate(res = dense_rank(rleid)) %>%
                                    ungroup() %>%
                                    mutate(res = ifelse(criterium, res, NA)) %>%
                                    select(-rleid)

                                    group criterium res
                                    <fct> <lgl> <int>
                                    1 A NA NA
                                    2 A TRUE 1
                                    3 A TRUE 1
                                    4 A TRUE 1
                                    5 A FALSE NA
                                    6 A FALSE NA
                                    7 A TRUE 2
                                    8 A TRUE 2
                                    9 A FALSE NA
                                    10 A TRUE 3
                                    11 A TRUE 3
                                    12 A TRUE 3
                                    13 B NA NA
                                    14 B FALSE NA
                                    15 B TRUE 1
                                    16 B TRUE 1
                                    17 B TRUE 1
                                    18 B FALSE NA





                                    share|improve this answer













                                    A different dplyr possibility using rle() and dense_rank() could be:



                                    df %>%
                                    group_by(group) %>%
                                    mutate(rleid = with(rle(criterium), rep(seq_along(lengths), lengths))) %>%
                                    group_by(group, criterium) %>%
                                    mutate(res = dense_rank(rleid)) %>%
                                    ungroup() %>%
                                    mutate(res = ifelse(criterium, res, NA)) %>%
                                    select(-rleid)

                                    group criterium res
                                    <fct> <lgl> <int>
                                    1 A NA NA
                                    2 A TRUE 1
                                    3 A TRUE 1
                                    4 A TRUE 1
                                    5 A FALSE NA
                                    6 A FALSE NA
                                    7 A TRUE 2
                                    8 A TRUE 2
                                    9 A FALSE NA
                                    10 A TRUE 3
                                    11 A TRUE 3
                                    12 A TRUE 3
                                    13 B NA NA
                                    14 B FALSE NA
                                    15 B TRUE 1
                                    16 B TRUE 1
                                    17 B TRUE 1
                                    18 B FALSE NA






                                    share|improve this answer












                                    share|improve this answer



                                    share|improve this answer










                                    answered 52 mins ago









                                    tmfmnktmfmnk

                                    3,7611516




                                    3,7611516





















                                        1














                                        A data.table option using rle



                                        library(data.table)
                                        DT <- as.data.table(dat)
                                        DT[, goal :=
                                        r <- rle(replace(criterium, is.na(criterium), FALSE))
                                        r$values <- with(r, cumsum(values) * values)
                                        out <- inverse.rle(r)
                                        replace(out, out == 0, NA)
                                        , by = group]
                                        DT
                                        # group criterium goal
                                        # 1: A NA NA
                                        # 2: A TRUE 1
                                        # 3: A TRUE 1
                                        # 4: A TRUE 1
                                        # 5: A FALSE NA
                                        # 6: A FALSE NA
                                        # 7: A TRUE 2
                                        # 8: A TRUE 2
                                        # 9: A FALSE NA
                                        #10: A TRUE 3
                                        #11: A TRUE 3
                                        #12: A TRUE 3
                                        #13: B NA NA
                                        #14: B FALSE NA
                                        #15: B TRUE 1
                                        #16: B TRUE 1
                                        #17: B TRUE 1
                                        #18: B FALSE NA


                                        data



                                        dat <- structure(list(group = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 
                                        1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L), .Label = c("A",
                                        "B"), class = "factor"), criterium = c(NA, TRUE, TRUE, TRUE,
                                        FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, NA, FALSE,
                                        TRUE, TRUE, TRUE, FALSE)), class = "data.frame", row.names = c(NA,
                                        -18L))





                                        share|improve this answer

























                                        • Wow, impressive. Thanks for introducing me to rleand inverse.rle. Gruß nach Leipzig.

                                          – Humpelstielzchen
                                          20 mins ago











                                        • @Humpelstielzchen Gern geschehen. Will try to simplify and explain the logic a bit.

                                          – markus
                                          16 mins ago
















                                        1














                                        A data.table option using rle



                                        library(data.table)
                                        DT <- as.data.table(dat)
                                        DT[, goal :=
                                        r <- rle(replace(criterium, is.na(criterium), FALSE))
                                        r$values <- with(r, cumsum(values) * values)
                                        out <- inverse.rle(r)
                                        replace(out, out == 0, NA)
                                        , by = group]
                                        DT
                                        # group criterium goal
                                        # 1: A NA NA
                                        # 2: A TRUE 1
                                        # 3: A TRUE 1
                                        # 4: A TRUE 1
                                        # 5: A FALSE NA
                                        # 6: A FALSE NA
                                        # 7: A TRUE 2
                                        # 8: A TRUE 2
                                        # 9: A FALSE NA
                                        #10: A TRUE 3
                                        #11: A TRUE 3
                                        #12: A TRUE 3
                                        #13: B NA NA
                                        #14: B FALSE NA
                                        #15: B TRUE 1
                                        #16: B TRUE 1
                                        #17: B TRUE 1
                                        #18: B FALSE NA


                                        data



                                        dat <- structure(list(group = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 
                                        1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L), .Label = c("A",
                                        "B"), class = "factor"), criterium = c(NA, TRUE, TRUE, TRUE,
                                        FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, NA, FALSE,
                                        TRUE, TRUE, TRUE, FALSE)), class = "data.frame", row.names = c(NA,
                                        -18L))





                                        share|improve this answer

























                                        • Wow, impressive. Thanks for introducing me to rleand inverse.rle. Gruß nach Leipzig.

                                          – Humpelstielzchen
                                          20 mins ago











                                        • @Humpelstielzchen Gern geschehen. Will try to simplify and explain the logic a bit.

                                          – markus
                                          16 mins ago














                                        1












                                        1








                                        1







                                        A data.table option using rle



                                        library(data.table)
                                        DT <- as.data.table(dat)
                                        DT[, goal :=
                                        r <- rle(replace(criterium, is.na(criterium), FALSE))
                                        r$values <- with(r, cumsum(values) * values)
                                        out <- inverse.rle(r)
                                        replace(out, out == 0, NA)
                                        , by = group]
                                        DT
                                        # group criterium goal
                                        # 1: A NA NA
                                        # 2: A TRUE 1
                                        # 3: A TRUE 1
                                        # 4: A TRUE 1
                                        # 5: A FALSE NA
                                        # 6: A FALSE NA
                                        # 7: A TRUE 2
                                        # 8: A TRUE 2
                                        # 9: A FALSE NA
                                        #10: A TRUE 3
                                        #11: A TRUE 3
                                        #12: A TRUE 3
                                        #13: B NA NA
                                        #14: B FALSE NA
                                        #15: B TRUE 1
                                        #16: B TRUE 1
                                        #17: B TRUE 1
                                        #18: B FALSE NA


                                        data



                                        dat <- structure(list(group = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 
                                        1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L), .Label = c("A",
                                        "B"), class = "factor"), criterium = c(NA, TRUE, TRUE, TRUE,
                                        FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, NA, FALSE,
                                        TRUE, TRUE, TRUE, FALSE)), class = "data.frame", row.names = c(NA,
                                        -18L))





                                        share|improve this answer















                                        A data.table option using rle



                                        library(data.table)
                                        DT <- as.data.table(dat)
                                        DT[, goal :=
                                        r <- rle(replace(criterium, is.na(criterium), FALSE))
                                        r$values <- with(r, cumsum(values) * values)
                                        out <- inverse.rle(r)
                                        replace(out, out == 0, NA)
                                        , by = group]
                                        DT
                                        # group criterium goal
                                        # 1: A NA NA
                                        # 2: A TRUE 1
                                        # 3: A TRUE 1
                                        # 4: A TRUE 1
                                        # 5: A FALSE NA
                                        # 6: A FALSE NA
                                        # 7: A TRUE 2
                                        # 8: A TRUE 2
                                        # 9: A FALSE NA
                                        #10: A TRUE 3
                                        #11: A TRUE 3
                                        #12: A TRUE 3
                                        #13: B NA NA
                                        #14: B FALSE NA
                                        #15: B TRUE 1
                                        #16: B TRUE 1
                                        #17: B TRUE 1
                                        #18: B FALSE NA


                                        data



                                        dat <- structure(list(group = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 
                                        1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L), .Label = c("A",
                                        "B"), class = "factor"), criterium = c(NA, TRUE, TRUE, TRUE,
                                        FALSE, FALSE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, NA, FALSE,
                                        TRUE, TRUE, TRUE, FALSE)), class = "data.frame", row.names = c(NA,
                                        -18L))






                                        share|improve this answer














                                        share|improve this answer



                                        share|improve this answer








                                        edited 2 mins ago

























                                        answered 52 mins ago









                                        markusmarkus

                                        15.3k11336




                                        15.3k11336












                                        • Wow, impressive. Thanks for introducing me to rleand inverse.rle. Gruß nach Leipzig.

                                          – Humpelstielzchen
                                          20 mins ago











                                        • @Humpelstielzchen Gern geschehen. Will try to simplify and explain the logic a bit.

                                          – markus
                                          16 mins ago


















                                        • Wow, impressive. Thanks for introducing me to rleand inverse.rle. Gruß nach Leipzig.

                                          – Humpelstielzchen
                                          20 mins ago











                                        • @Humpelstielzchen Gern geschehen. Will try to simplify and explain the logic a bit.

                                          – markus
                                          16 mins ago

















                                        Wow, impressive. Thanks for introducing me to rleand inverse.rle. Gruß nach Leipzig.

                                        – Humpelstielzchen
                                        20 mins ago





                                        Wow, impressive. Thanks for introducing me to rleand inverse.rle. Gruß nach Leipzig.

                                        – Humpelstielzchen
                                        20 mins ago













                                        @Humpelstielzchen Gern geschehen. Will try to simplify and explain the logic a bit.

                                        – markus
                                        16 mins ago






                                        @Humpelstielzchen Gern geschehen. Will try to simplify and explain the logic a bit.

                                        – markus
                                        16 mins ago


















                                        draft saved

                                        draft discarded
















































                                        Thanks for contributing an answer to Stack Overflow!


                                        • Please be sure to answer the question. Provide details and share your research!

                                        But avoid


                                        • Asking for help, clarification, or responding to other answers.

                                        • Making statements based on opinion; back them up with references or personal experience.

                                        To learn more, see our tips on writing great answers.




                                        draft saved


                                        draft discarded














                                        StackExchange.ready(
                                        function ()
                                        StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55606323%2frank-groups-within-a-grouped-sequence-of-true-false-and-na%23new-answer', 'question_page');

                                        );

                                        Post as a guest















                                        Required, but never shown





















































                                        Required, but never shown














                                        Required, but never shown












                                        Required, but never shown







                                        Required, but never shown

































                                        Required, but never shown














                                        Required, but never shown












                                        Required, but never shown







                                        Required, but never shown







                                        Popular posts from this blog

                                        名間水力發電廠 目录 沿革 設施 鄰近設施 註釋 外部連結 导航菜单23°50′10″N 120°42′41″E / 23.83611°N 120.71139°E / 23.83611; 120.7113923°50′10″N 120°42′41″E / 23.83611°N 120.71139°E / 23.83611; 120.71139計畫概要原始内容臺灣第一座BOT 模式開發的水力發電廠-名間水力電廠名間水力發電廠 水利署首件BOT案原始内容《小檔案》名間電廠 首座BOT水力發電廠原始内容名間電廠BOT - 經濟部水利署中區水資源局

                                        Prove that NP is closed under karp reduction?Space(n) not closed under Karp reductions - what about NTime(n)?Class P is closed under rotation?Prove or disprove that $NL$ is closed under polynomial many-one reductions$mathbfNC_2$ is closed under log-space reductionOn Karp reductionwhen can I know if a class (complexity) is closed under reduction (cook/karp)Check if class $PSPACE$ is closed under polyonomially space reductionIs NPSPACE also closed under polynomial-time reduction and under log-space reduction?Prove PSPACE is closed under complement?Prove PSPACE is closed under union?

                                        Is my guitar’s action too high? Announcing the arrival of Valued Associate #679: Cesar Manara Planned maintenance scheduled April 23, 2019 at 23:30 UTC (7:30pm US/Eastern)Strings too stiff on a recently purchased acoustic guitar | Cort AD880CEIs the action of my guitar really high?Μy little finger is too weak to play guitarWith guitar, how long should I give my fingers to strengthen / callous?When playing a fret the guitar sounds mutedPlaying (Barre) chords up the guitar neckI think my guitar strings are wound too tight and I can't play barre chordsF barre chord on an SG guitarHow to find to the right strings of a barre chord by feel?High action on higher fret on my steel acoustic guitar