在R中计算用户statusId=1的连续出现间隔天数
问题描述
原以为这是个复杂问题,实际可能很简单。我了解pivot_wider的用法,但同一用户存在多条记录、需将其实例拆分到不同行的场景让我困惑。
我有如下长格式表格:
# 示例数据 df <- data.frame( statusId = c(1, 1, 2, 2, 2, 2, 1, 2, 2, 1, 2, 2, 2), creationDate = c('2022-09-16 14:56:14.226 UTC', '2022-09-27 20:29:16.277 UTC', '2022-09-21 13:33:18.879 UTC', '2022-09-12 00:42:44.889 UTC', '2022-09-27 19:06:34.617 UTC', '2022-09-01 07:29:08.938 UTC', '2022-09-16 15:56:27.437 UTC', '2022-09-12 16:22:10.988 UTC', '2022-09-22 15:28:09.581 UTC', '2022-10-03 14:38:46.905 UTC', '2022-09-30 11:29:48.761 UTC', '2022-09-25 21:27:42.551 UTC', '2022-09-20 08:11:01.216 UTC'), Person = c('Person_1', 'Person_1', 'Person_2', 'Person_1', 'Person_2', 'Person_4', 'Person_3', 'Person_3', 'Person_4', 'Person_1', 'Person_1', 'Person_1', 'Person_1') ) # 打印数据框 df
输出表格如下:
| statusId | creationDate | Person |
|---|---|---|
| 1 | 2022-09-16 14:56:14.226 UTC | Person_1 |
| 1 | 2022-09-27 20:29:16.277 UTC | Person_1 |
| 2 | 2022-09-21 13:33:18.879 UTC | Person_2 |
| 2 | 2022-09-12 00:42:44.889 UTC | Person_1 |
| 2 | 2022-09-27 19:06:34.617 UTC | Person_2 |
| 2 | 2022-09-01 07:29:08.938 UTC | Person_4 |
| 1 | 2022-09-16 15:56:27.437 UTC | Person_3 |
| 2 | 2022-09-12 16:22:10.988 UTC | Person_3 |
| 2 | 2022-09-22 15:28:09.581 UTC | Person_4 |
| 1 | 2022-10-03 14:38:46.905 UTC | Person_1 |
| 2 | 2022-09-30 11:29:48.761 UTC | Person_1 |
| 2 | 2022-09-25 21:27:42.551 UTC | Person_1 |
| 2 | 2022-09-20 08:11:01.216 UTC | Person_1 |
我需要统计每个用户两次处于statusId=1状态之间的天数分布,忽略中间的其他状态。例如,Person_1在2022-09-16和2022-09-27处于statusId=1,间隔11天;之后在2022-10-03再次处于该状态,与上次间隔6天。最终希望得到如下格式的表格:
Person delay 1 Person_1 11 2 Person_1 6
解决方案
无需使用pivot_wider,用dplyr工具链即可简洁实现需求,步骤如下:
- 过滤出
statusId=1的记录,仅保留目标状态数据; - 将字符型日期转换为可计算的
POSIXct类型; - 按用户分组,对每组日期排序确保时间顺序正确;
- 用
lag()函数获取上一条状态记录的日期,计算天数差; - 过滤掉每组第一条无前置记录产生的NA值。
具体代码如下:
library(dplyr) result <- df %>% # 筛选statusId=1的记录 filter(statusId == 1) %>% # 转换日期格式为UTC时区的POSIXct mutate(creationDate = as.POSIXct(creationDate, tz = "UTC")) %>% # 按用户分组 group_by(Person) %>% # 按日期升序排序 arrange(creationDate) %>% # 计算与上一条记录的天数间隔,取整数 mutate(delay = as.integer(difftime(creationDate, lag(creationDate), units = "days"))) %>% # 移除无间隔的第一条记录 filter(!is.na(delay)) %>% # 取消分组并保留所需列 ungroup() %>% select(Person, delay) print(result)
运行后输出结果:
# A tibble: 2 × 2 Person delay <chr> <int> 1 Person_1 11 2 Person_1 6
内容的提问来源于stack exchange,提问作者I_like_insights
相关产品推荐
相关产品推荐

