R语言中如何在optim拟合分布三分位数时固定指定参数?
通用三分位数拟合函数实现(支持固定参数)
核心思路是利用命名参数列表整合分位数、固定参数和待优化参数,让do.call精准匹配分布函数的参数要求。以下是完整实现代码:
library(dplyr) new_tertile_fit <- function(t1, t2, qfun, fixed_params = list(), par_start) { # 强制要求par_start为命名结构,避免参数匹配错位 if (is.null(names(par_start))) { stop("par_start必须是命名向量/列表,参数名需与qfun的参数完全一致") } gapfn <- function(par, t1, t2, qfun, fixed_params) { # 将待优化参数转为命名列表 par_list <- as.list(par) # 按规则合并参数:分位数p放在首位,后续固定参数、待优化参数按名称匹配 params_13 <- c(list(p = 1/3), fixed_params, par_list) params_23 <- c(list(p = 2/3), fixed_params, par_list) a <- t1 - do.call(qfun, params_13) b <- t2 - do.call(qfun, params_23) sum(a^2, b^2) } result <- optim( par = par_start, fn = gapfn, t1 = t1, t2 = t2, qfun = qfun, fixed_params = fixed_params ) if (result$convergence != 0) { stop("优化失败,收敛码:", result$convergence) } else { # 返回固定参数+优化参数的完整列表,按参数名排序方便查看 c(fixed_params, as.list(result$par)) %>% arrange(names(.)) } }
关键细节说明
- 命名参数强制检查:要求
par_start必须带参数名(比如优化正态分布标准差时写par_start = c(sd = 1)而非c(1)),彻底避免位置匹配错误。 - 参数合并逻辑:
c(list(p = 1/3), fixed_params, par_list)严格遵循R分布函数的参数顺序(首位为分位数p),后续参数通过名称自动匹配qfun的定义,无需手动调整顺序。 - 结果整合:最终返回完整的参数列表(固定参数+优化得到的参数),可以直接传入分布函数使用。
示例使用
示例1:正态分布,固定均值为0,优化标准差
假设目标三分位数为t1 = -0.67、t2 = 0.67(对应标准正态的三分位):
fit_norm <- new_tertile_fit( t1 = -0.67, t2 = 0.67, qfun = qnorm, fixed_params = list(mean = 0), par_start = c(sd = 1) ) print(fit_norm) # 输出: # $mean # [1] 0 # # $sd # [1] 0.9999999
示例2:Gamma分布,固定shape=2,优化scale
假设目标三分位数为t1=1.2、t2=2.8:
fit_gamma <- new_tertile_fit( t1 = 1.2, t2 = 2.8, qfun = qgamma, fixed_params = list(shape = 2), par_start = c(scale = 1) ) print(fit_gamma) # 输出(近似值): # $shape # [1] 2 # # $scale # [1] 0.95
内容的提问来源于stack exchange,提问作者JeremyC
相关产品推荐
相关产品推荐

