如何基于起始值在列中生成重复数字序列(R语言tidyverse实现)
程序化生成desired列的解决方案
问题分析
你需要从治疗起始日期(对应treatment=1的行)开始,生成每个数字重复指定次数的序列,起始日期前的行全部为0,且能灵活调整重复次数。之前的尝试中,ifelse配合固定长度的rep序列会因为满足条件的行数与rep生成的长度不匹配,导致序列错位。
通用解决方案
以下方法无需硬编码日期,可自动识别治疗起始点,且能灵活设置重复次数:
library(tidyverse) # 原始数据 treatment <- c(0,0,0,0,1,0,0,0,0,0,0,0,0,0,0) df <- tibble(treatment) %>% mutate(date = seq(as_date("2016-01-01"), as_date("2016-01-15"), by = "day")) # 1. 设置重复次数(可按需修改) repeat_n <- 3 # 2. 自动获取治疗起始日期 treat_start_date <- df$date[df$treatment == 1] # 3. 生成程序化的desired列 df <- df %>% mutate( desired_program = case_when( # 治疗起始前的行设为0 date < treat_start_date ~ 0, # 根据与起始日期的天数差计算分组值 TRUE ~ floor((as.integer(date - treat_start_date)) / repeat_n) + 1 ) )
代码解释
- 自动识别起始日期:从
treatment列直接提取对应日期,避免硬编码,适配更大数据集。 - 天数差计算:
as.integer(date - treat_start_date)得到当前日期与起始日的间隔天数(起始日为0)。 - 分组逻辑:
floor(days_diff / repeat_n) +1将每repeat_n天划分为一组,对应desired列的一个数字,自动处理最后一组不足repeat_n的情况。
验证与调整
运行上述代码后,desired_program列会和你手动定义的desired列完全一致:
> df$desired_program [1] 0 0 0 0 1 1 1 2 2 2 3 3 3 4 4
若修改repeat_n=4,则生成的序列变为:
[1] 0 0 0 0 1 1 1 1 2 2 2 2 3 3 3
原代码问题说明
你之前的代码中,rep(1:4, each=3)生成固定长度为12的序列,但满足date >= "2016-01-05"的行有11行,R会循环该序列填充,导致最后一个元素重复,从而出现错位。而基于天数差的动态计算方法则完全避免了这个问题。
内容的提问来源于stack exchange,提问作者mikeytop
相关产品推荐
相关产品推荐

