Labeling contiguous chunks of observations without a for loop
r
Solution
Using `rle`
r <- rle(as.numeric(df$type))
df$label <- rep(seq(from=0, length=length(r$lengths)), times=r$lengths)
Not using `rle`, but `cumsum` over logicals that are coerced to numeric.
df$label <- c(0,cumsum(df$type[-1] != df$type[-length(df$type)]))
Both give:
> df
type label
1 a 0
2 a 0
3 a 0
4 b 1
5 b 1
6 c 2
7 c 2
8 c 2
9 c 2
10 d 3
11 e 4
Problem
I have a standard 'can-I-avoid-a-loop' problem, but cannot find a solution. I answered this question by @splaisan but I had to resort to some ugly contortions in the middle section, with a `for` and multiple `if` tests. I simulate a simpler version here in the hope that someone can give a better answer... THE PROBLEM Given a data structure like this: ``` df <- read.table(text = 'type a a a b b c c c c d e', header = TRUE) ``` I want to identify contiguous chunks of the same type and label them in groups. The first chunk should be labelled 0, the next 1, and so on. There is an indefinite number of chunks, and each chunk may be as short as only one member. ``` type label a 0 a 0 a 0 b 1 b 1 c 2 c 2 c 2 c 2 d 3 e 4 ``` MY SOLUTION I had to resort to a `for` loop to do this, here is the code: ``` 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 } ``` MY QUESTION Can anyone do this without the loop and conditionals?