为重复序列添加分组指示符

adding grouping indicator for repeating sequences

我认为这很简单,但失败了,无法从任何地方找到答案。

示例数据如下所示。我有 nro 运行ning 来自 1:x 并在随机点重新启动。我想创建 ind 变量,第一个 运行 为 1,第二个为 2...

tbl <- tibble(nro = c(rep(1:3, 1), rep(1:5, 1), rep(1:4, 1)))

最终结果应如下所示:

tibble(nro = c(rep(1:3, 1), rep(1:5, 1), rep(1:4, 1)),
       ind = c(rep(1, 3), rep(2, 5), rep(3, 4)))

 # A tibble: 12 x 2
     nro   ind
   <int> <dbl>
 1     1     1
 2     2     1
 3     3     1
 4     1     2
 5     2     2
 6     3     2
 7     4     2
 8     5     2
 9     1     3
10     2     3
11     3     3
12     4     3

我以为我可以用 ifelse 做点什么,但失败得很惨。

tbl %>%
  mutate(ind = ifelse(nro < lag(nro), 1 + lag(ind), 1))

我认为这需要某种循环。

对于相同长度的序列

您可以在 nro 变量上使用 group_by,然后只使用 row_number()

tbl %>% 
  group_by(nro) %>% 
  mutate(ind = row_number())

# A tibble: 12 x 2
# Groups:   nro [4]
#      nro   ind
#    <int> <int>
#  1     1     1
#  2     2     1
#  3     3     1
#  4     4     1
#  5     1     2
#  6     2     2
#  7     3     2
#  8     4     2
#  9     1     3
# 10     2     3
# 11     3     3
# 12     4     3

对于不同长度的序列

灵感来自 docendo discimus 的评论

tbl <- tibble(nro = c(rep(1:3, 1), rep(1:5, 1), rep(1:4, 1)))

tbl %>% 
  mutate(ind = cumsum(nro == 1))

但是,这仅限于以 1 开头的序列,因为只有 nro == 1TRUE 值会被累加。

因此,你应该考虑使用这个:

tbl %>% mutate(dif = nro - lag(nro)) %>% 
  mutate(dif = ifelse(is.na(dif), nro, dif)) %>% 
  mutate(ind = cumsum(dif < 0) + 1) %>% 
  select(-dif)

# A tibble: 12 x 2
#      nro   ind
#    <int> <dbl>
#  1     1     1
#  2     2     1
#  3     3     1
#  4     1     2
#  5     2     2
#  6     3     2
#  7     4     2
#  8     5     2
#  9     1     3
# 10     2     3
# 11     3     3
# 12     4     3