r - 识别组中 data.table 字段中的 n 个连续数字组
问题描述
此 data.table 显示学生参加的一年中的月份。
DT = data.table(
Student = c(1, 1, 1, 1, 1, 1, 1, 1, 1,
2, 2, 2, 2, 2, 2, 2, 2,
3, 3, 3, 3, 3, 3, 3, 3),
Month = c(1, 2, 3, 5, 6, 7, 8, 11, 12,
2, 3, 4, 5, 7, 8, 9, 10,
1, 2, 3, 5, 6, 7, 8, 9))
DT
Student Month
1: 1 1
2: 1 2
3: 1 3
4: 1 5
5: 1 6
6: 1 7
7: 1 8
8: 1 11
9: 1 12
10: 2 2
11: 2 3
12: 2 4
13: 2 5
14: 2 7
15: 2 8
16: 2 9
17: 2 10
18: 3 1
19: 3 2
20: 3 3
21: 3 5
22: 3 6
23: 3 7
24: 3 8
25: 3 9
我想确定连续三个月的时期(由时期中的第一个月确定)。这是数据表和合格期间的可视化。
1 2 3 4 5 6 7 8 9 10 11 12
1 * * * * * * * * *
[-------] [-------]
[-------]
2 * * * * * * * *
[-------] [-------]
[-------] [-------]
3 * * * * * * * *
[-------] [-------]
[-------]
[-------]
期望的输出:
id First_month_in_the_period
1 1
1 5
1 6
2 2
2 3
2 7
2 8
3 1
3 5
3 6
3 7
寻找 data.table(或 dplyr)解决方案。
解决方案
使用标准方法( cumsum...diff...condition
) 识别连续值的运行,然后将其与“学生”一起用作分组变量。在每个组中,根据每次运行的长度创建序列并添加到第一个月。
DT[ , .(start = if(.N >= 3) Month[1] + 0:(.N - 3)),
by = .(Student, r = cumsum(c(1L, diff(Month) > 1)))]
# Student r start
# 1: 1 1 1
# 2: 1 2 5
# 3: 1 2 6
# 4: 2 3 2
# 5: 2 3 3
# 6: 2 4 7
# 7: 2 4 8
# 8: 3 4 1
# 9: 3 5 5
# 10: 3 5 6
# 11: 3 5 7
等效dplyr
替代方案:
DT %>%
group_by(Student, r = cumsum(c(1L, diff(Month) > 1))) %>%
summarise(list(data.frame(start = if(n() >= 3) Month[1] + 0:(n() - 3)))) %>%
tidyr::unnest()
# # A tibble: 11 x 3
# # Groups: Student [3]
# Student r start
# <dbl> <int> <dbl>
# 1 1 1 1
# 2 1 2 5
# 3 1 2 6
# 4 2 3 2
# 5 2 3 3
# 6 2 4 7
# 7 2 4 8
# 8 3 4 1
# 9 3 5 5
# 10 3 5 6
# 11 3 5 7
推荐阅读
- javascript - 获取仅给定特定时间的日期 - 今天
- javascript - 在 Javascript 中将对象数组转换为键值结构
- scip - 如何为 SCIP 提供启发式目标解决方案
- python - 如何在numpy数组中复制值?
- mysql - MySQL工作台工作区恢复
- javascript - 在脚本标签中使用 Promises 不起作用?
- php - 根据 ACF 日期字段值过滤自定义帖子类型
- android - 包含自定义视图的可扩展文本
- python - Plotly.py 在图例上合并 2 条迹线,以便一键隐藏或显示它们
- javascript - 嵌套表上的jQuery slideDown