R语言按时间周期自动分配组ID的技术实现问题
解决按ID分组的时间序列周期分配问题
看起来你遇到的核心问题是分组方式不对,导致周期计算逻辑失效了。让我们一步步来修复这个问题:
你的代码出错原因
你之前用了group_by(date, id),这会把每一行日期+ID的组合当成单独的分组,所以length(date)在每个组里都是1,你的周期生成逻辑自然就无法正确运行,最后只会返回最后一个周期编号。正确的做法应该是仅按id分组,这样每个组对应同一个ID的所有日期序列。
解决方案代码
我们可以用dplyr按ID分组后,针对每个组的日期长度计算周期:
首先加载必要的包:
library(dplyr)
定义你需要的子周期数n,然后处理数据框:
# 定义子周期数,比如你例子中的3或4 n <- 3 df <- df %>% group_by(id) %>% mutate( # 获取当前ID对应的总天数 total_days = n(), # 计算前n-1个周期的每个周期天数 period_length = floor(total_days / n), # 生成周期编号:前n-1组按固定长度重复,最后一组收剩余数据 period = c( rep(seq(1, n-1), each = period_length), rep(n, total_days - (n-1)*period_length) ) ) %>% # 移除临时计算列 select(-total_days, -period_length) %>% ungroup()
验证效果
- 当
n=4时,第一个ID的20天会被分成4个各5天的周期,第二个ID的24天会分成4个各6天的周期,完全符合你最初的期望。 - 当
n=3时,第一个ID的20天会生成c(rep(1,6), rep(2,6), rep(3,8)),和你描述的需求一致。
更简洁的写法(可选)
如果不想保留临时计算列,也可以把逻辑整合到一行:
n <- 3 df <- df %>% group_by(id) %>% mutate( period = c( rep(1:(n-1), each = floor(n() / n)), rep(n, n() - (n-1)*floor(n() / n)) ) ) %>% ungroup()
这样就能完美实现你想要的:每个ID的日期序列被分成n个周期,前n-1个周期长度一致,最后一个周期包含剩余的所有数据。
内容的提问来源于stack exchange,提问作者cara mathias
相关产品推荐
相关产品推荐

