1) data.table/dplyr 按ID和streak分组(使用符号的rleid计算),汇总结果并丢弃我们不再需要的streak。 rleid 是 data.table 中唯一使用的函数。
library(data.table)
library(dplyr)
dat %>%
group_by(ID, streak = rleid(sign(`Weight Change`))) %>%
summarize(`Streak Length` = n(), `Weight Change` = sum(`Weight Change`), .groups = "drop") %>%
select(-streak)
给予:
# A tibble: 6 x 3
ID `Streak Length` `Weight Change`
<int> <int> <dbl>
1 1 2 -0.7
2 1 2 1.5
3 1 1 -0.5
4 2 2 -0.4
5 2 1 0.6
6 2 2 -0.8
2) collapse/magrittr 我们可以交替使用 collapse 包和 magrittr。 groupid 类似于 data.table 中的 rleid。
library(collapse)
library(magrittr)
dat %>%
tfm(streak = groupid(sign(`Weight Change`)), `Streak Length` = 1) %>%
collap(~ ID + streak, fsum, cols = c("Weight Change", "Streak Length")) %>%
slt(-streak)
给予:
ID Weight Change Streak Length
1 1 -0.7 2
2 1 1.5 2
3 1 -0.5 1
4 2 -0.4 2
5 2 0.6 1
6 2 -0.8 2
3) data.table 仅使用 data.table 我们有:
as.data.table(dat)[, .(`Streak Length` = .N, `Weight Change` = sum(`Weight Change`)),
by = .(ID, rleid(sign(`Weight Change`)))][, -2]
给予:
ID Streak Length Weight Change
1: 1 2 -0.7
2: 1 2 1.5
3: 1 1 -0.5
4: 2 2 -0.4
5: 2 1 0.6
6: 2 2 -0.8
注意
dat <-
structure(list(ID = c(1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L),
Week = c(1L, 2L, 3L, 4L, 5L, 1L, 2L, 3L, 4L, 5L), `Weight Change` = c(-0.5,
-0.2, 1, 0.5, -0.5, -0.2, -0.2, 0.6, -0.5, -0.3)), class = "data.frame", row.names = c(NA,
-10L))