You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

在Shiny Flexdashboard中使用fitdistrplus包拟合Pearson-3分布时出现函数未定义错误的求助

在Shiny Flexdashboard中使用fitdistrplus包拟合Pearson-3分布时出现函数未定义错误的求助

问题分析

你遇到的 ERROR: The dPIII function must be defined 错误,核心原因是fitdistrplus的fitdist函数在查找自定义分布的概率密度/分布/分位数/随机数函数时,无法在当前作用域内找到你定义的dPIII等函数

在Shiny的运行环境中,普通代码块里定义的函数默认属于局部环境,而eventReactive内部运行的fitdist会优先在全局环境或自身反应式环境中查找依赖函数,这就导致你在单独代码块里定义的dPIII/pPIII等函数被"隔离",无法被fitdist找到。

虽然你遵循了fitdist的命名规则(用PIII作为分布名,前缀加d/p/q/r),但作用域问题直接破坏了这种自动匹配逻辑。


解决方案

这里提供两种稳妥的解决办法,推荐第一种(显式指定函数),彻底规避作用域相关的坑:

方案1:在fitdist中显式指定所有分布函数

直接在调用fitdist时,通过dfun/pfun/qfun/rfun参数手动传递你定义的函数,跳过自动查找逻辑,从根源解决作用域问题。

修改你# Use fitdistrplus with the PIII previously defined代码块中的fit_p3部分:

fit_p3 <- fitdistrplus::fitdist(
  data = TS_data()$value,
  distr = "PIII",  # 分布名称仅作标识,不影响显式传入的函数
  start = start,
  control = list(maxit = 1000),
  dfun = dPIII,    # 显式指定概率密度函数
  pfun = pPIII,    # 显式指定累积分布函数
  qfun = qPIII,    # 显式指定分位数函数
  rfun = rPIII     # 显式指定随机数生成函数
)

方案2:将PIII函数定义在全局环境

dPIII/pPIII等函数的定义移到setup代码块中(setup块的代码会在全局环境执行),这样fitdist的自动查找逻辑就能顺利找到这些函数。

修改你的setup代码块,加入函数定义:

```{r setup, include=FALSE}
# 导入包
library(flexdashboard)
library(shiny)
library(tidyverse)
library(openxlsx)
library(PearsonDS)
library(e1071)
library(data.table)

# 把PIII函数定义放在setup块(全局环境)
## Pearson type 3
dPIII <- function(x, shape, location, scale) {
  PearsonDS::dpearsonIII(x, shape, location, scale, log = FALSE)
}
pPIII <- function(q, shape, location, scale) {
  PearsonDS::ppearsonIII(q, shape, location, scale, lower.tail = TRUE, log.p = FALSE)
}
qPIII <- function(p, shape, location, scale) {
  PearsonDS::qpearsonIII(p, shape, location, scale, lower.tail = TRUE, log.p = FALSE)
}
rPIII <- function(n, shape, location, scale) {
  PearsonDS::rpearsonIII(n, shape, location, scale)
}
修改后,你原来的`# Define LPIII`代码块可以直接删除或注释掉。

---

### 额外注意事项
1. 确保输入数据有效:如果数据存在缺失值,建议在传入`fitdist`前用`na.omit(TS_data()$value)`清理;
2. 初始值合理性检查:你的矩估计初始值`start`中,`shape`参数必须为正(Pearson-3分布的形状参数要求>0),如果数据偏度为负,`my_scale`会是负数,这符合Pearson-3的位置-尺度参数定义,但要确保初始值不会导致后续MLE迭代报错;
3. 反应式依赖完整性:确认`TS_data()`在`submit_button`点击时已经正确加载数据,避免因数据为空导致的连锁错误。

按照上述方法修改后,`fitdist`就能正常识别你的PIII分布函数,不会再报函数未定义的错误了。

火山引擎 最新活动