按ID与年份分组运行Gompertz模型,生成至目标值的日期与结果数据集
解决Gompertz模型分组生成序列的问题
这是个很常见的分组迭代计算场景,用R的tidyverse工具链就能轻松搞定,下面是具体的实现步骤和代码:
前置准备
首先确认你已经安装并加载了必要的包:
library(grofit) library(tidyverse)
我们的核心需求是:按id和year分组,从每组的lambda起始日开始,逐日计算Gompertz模型的输出值x,直到x四舍五入到两位小数等于100为止,最终生成包含分组信息、日期和对应x值的数据集。
实现思路
- 先写一个自定义函数,负责单组的序列生成:输入该组的
lambda和mu,从起始日开始循环计算,直到x达到100,返回该组的日期-x序列。 - 用分组工具(比如
dplyr的group_modify)把这个函数应用到每一组,自动合并结果。
完整代码
第一步:定义单组处理函数
generate_gompertz_data <- function(lambda_start, mu_param) { # 初始化空的结果数据框 output <- tibble(day = integer(), x = numeric()) current_day <- lambda_start repeat { # 计算当前日期的Gompertz值,保留两位小数 x_val <- round(grofit::gompertz(current_day, A = 100, mu = mu_param, lambda = lambda_start), 2) # 添加当前记录到结果 output <- output %>% add_row(day = current_day, x = x_val) # 终止条件:x值达到100 if (x_val == 100) break # 推进到下一天 current_day <- current_day + 1 } return(output) }
第二步:分组处理原数据集
# 你的原始数据集 df <- data.frame( id = c(1,1,2,2), year = c(1981,1982,1981,1982), mu= c(35,32,33,28), lambda = c(275,278,284,296) ) # 分组生成最终结果 final_output <- df %>% group_by(id, year) %>% group_modify(~ generate_gompertz_data(.$lambda, .$mu)) %>% ungroup() # 查看结果示例 print(final_output, n = 20)
补充说明
- 这里用
round(x_val, 2) == 100作为终止条件,和你给出的示例逻辑完全一致,确保生成的序列包含第一次达到100的日期。 - 如果担心浮点精度问题(比如实际计算值是99.9999999,四舍五入后是100),可以把终止条件改成
x_val >= 99.995,这样能更精准地捕捉到即将四舍五入为100的数值。 - 也可以用
purrr::pmap来实现,写法更简洁:
final_output_pmap <- df %>% mutate(sequence = pmap(list(lambda, mu), generate_gompertz_data)) %>% unnest(sequence) %>% select(id, year, day, x)
内容的提问来源于stack exchange,提问作者89_Simple
相关产品推荐
相关产品推荐

