title: R: Renumber subgroups within groups, starting with 1 each time
body: <p>What I have is a dataset "df" that has subgroups within groups, except the subgroups are numbered 1-N universally, rather than 1-n within each group. Currently it looks like this:</p>
  
  <pre><code>df = data.frame( c( rep(58, 10), rep(59, 12) ), 
                   c( rep(417, 4), rep(418, 5), rep(419, 1), rep(420, 7), 
                     rep(421, 5) ) )
  
  colnames(df) = c("group", "subgroup_global")
  
  df
  
       group      subgroup_global
  1      58              417
  2      58              417
  3      58              417
  4      58              417
  5      58              418
  6      58              418
  7      58              418
  8      58              418
  9      58              418
  10     58              419
  11     59              420
  12     59              420
  13     59              420
  14     59              420
  15     59              420
  16     59              420
  17     59              420
  18     59              421
  19     59              421
  20     59              421
  21     59              421
  22     59              421
  </code></pre>
  
  <p>I'd like to turn it into this, so the first subgroup within each group restarts at 1:</p>
  
  <pre><code>       group   subgroup_global subgroup
  1      58              417         1
  2      58              417         1
  3      58              417         1
  4      58              417         1
  5      58              418         2
  6      58              418         2
  7      58              418         2
  8      58              418         2
  9      58              418         2
  10     58              419         3
  11     59              420         1
  12     59              420         1
  13     59              420         1
  14     59              420         1
  15     59              420         1
  16     59              420         1
  17     59              420         1
  18     59              421         2
  19     59              421         2
  20     59              421         2
  21     59              421         2
  22     59              421         2
  </code></pre>
  
  <p>I have figured out a very cumbersome way to do this with essentially two nested loops:</p>
  
  <pre><code>renumber &lt;- function(c) {
                  c$subgroup &lt;- 1
                  x &lt;- which(!duplicated(c$subgroup_global))
                  c[x, "subgroup"] &lt;- 1:length(x)
                  for(i in x) {
                          val = c[i, "subgroup"]
                          valGlobal = c[i, "subgroup_global"]
                          rows = which(c$subgroup_global == as.numeric(valGlobal))
                          c[rows, "subgroup"] = val
                          }
                  c
  }
  </code></pre>
  
  <p>Next, I iterate this "renumber" function within each group of the dataset (you'll notice I sneak in the "filter" dplyr function among a sea of base R):</p>
  
  <pre><code>df_renumbered &lt;- data.frame()
  for(i in unique(df$group)) {
          df_partial &lt;- filter(df, group == i)
          df_partial &lt;- renumber(df_partial)
          df_renumbered &lt;- rbind(df_renumbered, df_partial)
  }
  df_renumbered
  </code></pre>
  
  <p>Besides looking inefficient, this code takes (for all intents and purposes) an infinite amount of time to run on my real dataset, which contains 200,000+ rows, 3,000+ groups, and 27,000+ subgroups. Could you please provide a feasible solution using either dplyr or base R or some combo of the two?</p>