You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在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

输出表格如下:

statusIdcreationDatePerson
12022-09-16 14:56:14.226 UTCPerson_1
12022-09-27 20:29:16.277 UTCPerson_1
22022-09-21 13:33:18.879 UTCPerson_2
22022-09-12 00:42:44.889 UTCPerson_1
22022-09-27 19:06:34.617 UTCPerson_2
22022-09-01 07:29:08.938 UTCPerson_4
12022-09-16 15:56:27.437 UTCPerson_3
22022-09-12 16:22:10.988 UTCPerson_3
22022-09-22 15:28:09.581 UTCPerson_4
12022-10-03 14:38:46.905 UTCPerson_1
22022-09-30 11:29:48.761 UTCPerson_1
22022-09-25 21:27:42.551 UTCPerson_1
22022-09-20 08:11:01.216 UTCPerson_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工具链即可简洁实现需求,步骤如下:

  1. 过滤出statusId=1的记录,仅保留目标状态数据;
  2. 将字符型日期转换为可计算的POSIXct类型;
  3. 按用户分组,对每组日期排序确保时间顺序正确;
  4. 用lag()函数获取上一条状态记录的日期,计算天数差;
  5. 过滤掉每组第一条无前置记录产生的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 05:45:16