如何处理 dplyr 中 min_rank 的变化

How to handle variation of min_rank in dplyr

我有以下data.frame

df

id  name  strength days date
1   a     10       20   10
1   a     10       30   11
1   a     10       10   12
1   a     5        20   14
1   a     5        10   15
1   a     10       20   16
2   b     10       15   09...

我需要找出每组 id 连续使用名称和强度组合的天数总和。例如。预期结果

id  name  strength sumOfDays
1   a     10       60
1   a     5        30
1   a     10       20

我正在尝试 min_rank 同样使用 :

y <- df %>%
  group_by(id, name) %>%
  mutate(group = min_rank(strength ))

这给了我一个不需要的分组(逻辑上正确),因为它将所有 a-10 分组在一起但不考虑日期的顺序:

df
id  name  strength group
1   a     10       3
1   a     10       3
1   a     10       3
1   a     5        1
1   a     5        1
1   a     10       3
2   b     10       1...

我们可以使用 data.table 中的 rleid 函数来创建用于分组的列。

library(dplyr)
library(data.table)

dat2 <- dat %>%
  group_by(id, name, strength, Group = rleid(strength)) %>%
  summarise(sumOfDays = sum(days)) %>%
  ungroup() %>%
  arrange(id, Group) %>%
  select(-Group)
dat2
# # A tibble: 4 x 4
#      id name  strength sumOfDays
#   <int> <chr>    <int>     <int>
# 1     1 a           10        60
# 2     1 a            5        30
# 3     1 a           10        20
# 4     2 b           10        15

数据

dat <- read.table(text = "id  name  strength days date
1   a     10       20   10
                  1   a     10       30   11
                  1   a     10       10   12
                  1   a     5        20   14
                  1   a     5        10   15
                  1   a     10       20   16
                  2   b     10       15   09",
                  header = TRUE, stringsAsFactors = FALSE)

这是 base R 版本 rleaggregate

rl <-  rle(dat$strength)
aggregate(days ~., transform(dat, Group = rep(seq_along(rl$values), 
              rl$lengths))[-5], FUN = sum)[-4]
#   id name strength days
#1  1    a       10   60
#2  1    a        5   30
#3  1    a       10   20
#4  2    b       10   15