Rotulando pedaços contíguos de observações sem um loop for

Eu tenho um problema padrão 'can-I-avoid-a-loop', mas não consigo encontrar uma solução.

eu respondiesta pergunta por @splaisan mas eu tive que recorrer a algumas contorções feias na seção do meio, com umfor e múltiplosif testes. Eu simulo uma versão mais simples aqui na esperança de que alguém possa dar uma resposta melhor ...

O PROBLEMA

Dada uma estrutura de dados como esta:

df <- read.table(text = 'type
a
a
a
b
b
c
c
c
c
d
e', header = TRUE)

Quero identificar partes contíguas do mesmo tipo e rotulá-las em grupos. O primeiro pedaço deve ser rotulado como 0, o próximo 1 e assim por diante. Há um número indefinido de partes, e cada parte pode ser tão curta quanto apenas um membro.

type    label
   a    0
   a    0
   a    0
   b    1
   b    1
   c    2
   c    2
   c    2
   c    2
   d    3
   e    4

MINHA SOLUÇÃO

Eu tive que recorrer a umfor loop para fazer isso, aqui está o código:

label <- 0
df$label <- label

# LOOP through the label column and increment the label
# whenever a new type is found
for (i in 2:length(df$type)) {
    if (df$type[i-1] != df$type[i]) { label <- label + 1 }
    df$label[i] <- label
}

MINHA PERGUNTA

Alguém pode fazer isso sem o loop e condicionais?

questionAnswers(3)

yourAnswerToTheQuestion