Это решение не требует ни циклов, ни rle
, ни других умных функций; просто функции merge
и aggregate
.
Сначала готовятся ваши данные (использовался код Андри):
df <- data.frame(
x = rep(letters[1:3], c(10, 8, 10)),
y = rep(paste("b", c(1:3, 1:2, 1:4) ,sep=""), c(3, 2, 5, 4, 4, 1, 3, 2, 4))
)
Решение:
minmax <- with(df, merge(
aggregate(seq(x), by = list(x = x, y = y), min),
aggregate(seq(x), by = list(x = x, y = y), max)
))
names(minmax)[3:4] = c("min", "max") # unique pairs with min/max global order
result <- with(merge(df, minmax),
data.frame(x, y, count = seq(x) - min + 1, last = seq(x) == max))
В этом решении предполагается, что входные данные отсортированы, как вы сказали, но их можно легко изменить для работы с несортированными таблицами (и сохранить их в несортированном виде).