R语言归一化后验分布数值积分报错:length=21 coercion to logical(1)
修复后验分布归一化积分的问题
问题核心原因
你的代码存在两个关键错误导致报错:
prior函数使用了仅支持单个值判断的if+&&逻辑,而integrate函数会传入向量形式的参数,触发逻辑值长度不匹配的错误。- 计算后验均值时,积分上下限设置完全相同(区间长度为0,无意义),同时变量名拼写错误(将存储积分结果的
integr误写为integral)。
修复步骤
1. 重构prior函数为向量化版本
替换原函数中的if判断为支持向量输入的ifelse,确保能处理integrate传入的批量参数:
prior <- function(a_true) { ifelse(a_true >= (a1 - sigma_a1) & a_true <= (a1 + sigma_a1), 1 / (2 * sigma_a1), 0) }
也可以用逻辑索引的方式实现,效果一致:
prior <- function(a_true) { out <- numeric(length(a_true)) valid_range <- a_true >= (a1 - sigma_a1) & a_true <= (a1 + sigma_a1) out[valid_range] <- 1 / (2 * sigma_a1) out }
2. 修正后验均值计算的积分参数
调整上下限为有效区间,并修正变量名拼写:
a_true_estimated <- integrate(function(a_true) { a_true * posterior(a_true) / integr$value }, lower = a1 - sigma_a1, upper = a1 + sigma_a1)$value
完整修复后代码
a1 <- 0.012 sigma_a1 <- 0.001 likelihood <- function(a_true) { (1 / (sqrt(2 * pi) * sigma_a1 )) * exp(-((a1 - a_true) ^ 2) / (2 * (sigma_a1 ^ 2))) } prior <- function(a_true) { ifelse(a_true >= (a1 - sigma_a1) & a_true <= (a1 + sigma_a1), 1 / (2 * sigma_a1), 0) } posterior <- function(a_true) { likelihood(a_true) * prior(a_true) } # 归一化后验分布 integr <- integrate(posterior, lower = a1 - sigma_a1, upper = a1 + sigma_a1) # 计算后验均值 a_true_estimated <- integrate(function(a_true) { a_true * posterior(a_true) / integr$value }, lower = a1 - sigma_a1, upper = a1 + sigma_a1)$value
内容的提问来源于stack exchange,提问作者david clarck
相关产品推荐
相关产品推荐

