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

在dplyr::mutate中使用slider::slide_index_dbl报错的技术求助

问题:slider包计算窗口统计时出现「端点必须升序」错误

场景还原

我有一个包含Person(用户ID)、NoShow(是否爽约,1=是)、date(预约日期)的数据框,模拟数据示例:

df <- data.frame(Person = c('334','334','334','334','334','334','334','334','334'), 
                 NoShow = c(1,1,1,0,1,1,0,1,0), 
                 date = c('2014-01-01','2016-06-01','2017-01-01','2018-05-01','2021-01-01','2021-06-03','2022-04-14','2022-04-14','2023-05-03')
)

为统计每条记录日期未来2年内的爽约总数,我用slider包写了如下代码:

library(lubridate); library(dplyr); library(slider)
df %>%
  mutate(date = ymd(date)) %>%
  group_by(Person) %>%
  arrange(Person, date) %>% # slider要求分组内日期必须排序
  mutate(no_shows_next2yr = slide_index_dbl(
    NoShow, date, sum, .before = days(-1), .after = years(2)
  ))

这段代码在模拟数据上运行正常,但放到结构完全一致的真实数据时,触发如下错误:

Error in `mutate()`:
! Problem while computing `no_shows_next2yr = slider::slide_index_dbl(...)`.
ℹ The error occurred in group 2326: Person = "456".
Caused by error in `slider::slide_index_dbl()`:
ℹ In locations: 5
! Endpoints generated by `.after` must be in ascending order.

我已经检查了报错的用户组(Person=456),确认Person和date都按升序排列,但找不到问题根源。

排查方案与解决办法

1. 重复日期导致窗口计算冲突

当同一用户有多条完全相同日期的记录时,slide_index_dbl在计算窗口端点时可能出现逻辑混乱——虽然模拟数据里有重复日期没报错,但真实数据中重复日期的分布可能触发了边缘情况。

解决办法:给重复日期添加微小时间差(比如秒数),确保每个日期唯一:

df %>%
  mutate(date = ymd(date)) %>%
  group_by(Person, date) %>%
  mutate(date = date + seconds(row_number() - 1)) %>% # 同日期的记录依次加0、1、2...秒
  ungroup() %>%
  group_by(Person) %>%
  arrange(Person, date) %>%
  mutate(no_shows_next2yr = slide_index_dbl(
    NoShow, date, sum, .before = days(-1), .after = years(2)
  ))

2. 闰年导致的日期计算异常

lubridate::years(2)在处理闰年相关日期(比如2月29日)时,可能生成不符合预期的日期,导致窗口端点的顺序出现异常。

解决办法:

  • 方案一:用固定天数近似2年(忽略闰年差异):
mutate(no_shows_next2yr = slide_index_dbl(
  NoShow, date, sum, .before = days(-1), .after = days(730)
))
  • 方案二:用add_with_rollback处理闰年,避免无效日期:
mutate(no_shows_next2yr = slide_index_dbl(
  NoShow, date, sum, 
  .before = days(-1), 
  .after = function(x) add_with_rollback(x, years(2), roll_to_first = TRUE)
))

3. 日期格式转换不彻底

看似已排序的日期,可能存在部分未成功转换为Date类型的记录,或者存在NA值,导致窗口计算逻辑出错。

验证与修复:
先提取报错分组的数据,检查日期类型和完整性:

problem_group <- df %>% filter(Person == "456") %>% mutate(date = ymd(date))
str(problem_group$date) # 确认是Date类型,而非字符型
table(is.na(problem_group$date)) # 检查是否有转换失败的NA值
all(problem_group$date == arrange(problem_group, date)$date) # 确认排序是否真的正确

如果发现问题,重新转换并清理日期:

df %>%
  mutate(date = ymd(date, quiet = TRUE)) %>% # 静默转换,失败的记录设为NA
  filter(!is.na(date)) %>% # 移除无效日期的记录
  group_by(Person) %>%
  arrange(Person, date) %>%
  mutate(no_shows_next2yr = slide_index_dbl(
    NoShow, date, sum, .before = days(-1), .after = years(2)
  ))

内容的提问来源于stack exchange,提问作者Ray

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 20:53:15