如何计算疫情暴发时长?求峰值后感染趋稳的首日(R语言)
问题描述
已通过代码out[which.max(out$I), 1]定位到疫情峰值对应的time列日期,现需找到该峰值日之后,感染人数(数据框I列)首次趋稳的日期。尝试用for循环从峰值日遍历至数据框末尾,但现有代码存在问题。
数据框结构示例:
| time | S | I | D |
|---|---|---|---|
| 0 | 345299.0 | 1.000000 | 0.0000000 |
| 1 | 345298.1 | 1.465194 | 0.4328117 |
| 2 | 345296.8 | 2.146788 | 1.0669638 |
| 3 | 345294.9 | 3.145440 | 1.9961145 |
| 4 | 345292.0 | 4.608629 | 3.3574897 |
| 5 | 345287.9 | 6.752414 | 5.3521414 |
尝试的错误代码:
lengthofoutbreak <- 1000 for (i in out[which.max(out$I), 1]:length(out[out$I]) { if (i < lengthofoutbreak) { lengthofoutbreak <- out$I } return(lengthofoutbeak) } for (i in out$I) { if (out$I < lengthofoutbreak) { lengthofoutbreak <- out[out$I, 1] } return(lengthofoutbeak) }
问题分析
原代码存在多个问题:
- 语法错误:第一个for循环缺少闭合括号
) - 逻辑混乱:直接将整个
I列赋值给lengthofoutbreak,而非单个值;return语句会直接终止循环,无法完成遍历 - 未定义“趋稳”的判断标准:没有明确感染人数趋稳的条件(比如变化量/变化率低于阈值、连续多天稳定)
正确实现方法
首先需要明确趋稳的定义,这里以「连续2天感染人数的变化率低于1%」为例(可根据需求调整阈值和连续天数),实现步骤如下:
- 定位疫情峰值的行索引和对应日期
# 找到峰值所在的行索引 peak_row <- which.max(out$I) # 峰值对应的time日期 peak_time <- out$time[peak_row]
- 定义趋稳的判断标准
stable_change_rate <- 0.01 # 变化率阈值(1%) consecutive_days <- 2 # 需要连续满足的天数
- 从峰值后开始遍历,寻找首次趋稳的日期
stable_time <- NA # 初始化结果变量 # 从峰值行的下一行开始遍历到数据框末尾 for (i in (peak_row + 1):nrow(out)) { # 计算当前日与前一日的感染人数变化率 change_rate <- abs(out$I[i] - out$I[i-1]) / out$I[i-1] # 当遍历到足够天数后,检查连续n天是否都满足趋稳条件 if (i >= peak_row + consecutive_days) { # 获取最近consecutive_days天的变化率 recent_rates <- sapply((i - consecutive_days + 1):i, function(x) { abs(out$I[x] - out$I[x-1]) / out$I[x-1] }) # 如果所有变化率都低于阈值,记录日期并退出循环 if (all(recent_rates < stable_change_rate)) { stable_time <- out$time[i] break } } } # 输出结果 cat("峰值后首次趋稳的日期:", stable_time, "\n")
代码说明
- 先通过
which.max(out$I)获取峰值的行索引,比直接取time值更方便后续遍历 - 用变化率判断趋稳比绝对变化量更合理,避免因感染人数基数不同导致误判
- 通过检查连续多天的变化率,确保不是偶然的单日波动,而是真正进入稳定阶段
内容的提问来源于stack exchange,提问作者Hen
相关产品推荐
相关产品推荐

