You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在R中完善PDF统计量计算函数:添加中位数及归一化边界求解

R中PDF函数的中位数计算与边界确定实现方案

问题背景

已实现R函数计算自定义PDF的均值、方差,需新增两个功能:

  • 计算PDF的中位数(即满足积分值为0.5的点)
  • 给定一个端点,确定另一边界使函数在该区间的积分值为1
    测试用例为f(x)=x,不希望用计算量大且易出错的while循环。

原函数代码:

dense <- function(lower1=0,upper1,f=function(x)x, uppertail = F ){
      
    xf<-function(x){
      return(x*f(x))
    }
    
      
    xxf<-function(x){
      return(x*x*f(x))
    }
    
  if(uppertail == F){
    
    m0f<-integrate(f,lower=lower1,upper = upper1)
    m1f<-integrate(f = xf ,lower=lower1,upper = upper1) 
    m2f<-integrate(xxf ,lower=lower1,upper = upper1) 
    
   v <-(m2f$value)-(m1f$value)^2
    return(paste("variance =",v,"mean/expected = ",m1f$value,"intergral = ",m0f$value))
      
  }else{ 
      integrate(f=f,lower=upper1,upper = lower1)
    
    m0f<-integrate(f,lower=upper1,upper = lower1)
    m1f<-integrate(f = xf ,lower=upper1,upper = lower1) 
    m2f<-integrate(xxf ,lower=upper1,upper = lower1) 
      
     v <-(m2f$value)-(m1f$value)^2

    return(paste("variance =",v,"mean/expected = ",m1f$value,"intergral = ",m0f$value))

  }
}

解决方案

1. 核心思路

不用while循环,改用R内置的uniroot()函数求解方程:

  • 中位数:构造函数CDF(x) - 0.5 = 0,其中CDF是PDF从区间端点到x的积分,求解x
  • 边界确定:构造函数积分值 - 1 = 0,求解未知端点

2. 整合后的完整函数

修改原函数,新增中位数计算和边界确定功能,同时将返回结果改为更易处理的列表格式:

dense <- function(lower1 = 0, upper1 = NULL, f = function(x) x, uppertail = FALSE, find_bound = NULL) {
  # 定义辅助函数
  xf <- function(x) x * f(x)
  xxf <- function(x) x^2 * f(x)
  
  # 边界确定逻辑:给定一个端点,找另一个使积分=1
  if (!is.null(find_bound)) {
    if (find_bound == "lower") {
      # 已知upper1,找lower使得积分从lower到upper1=1
      target_fun <- function(l) integrate(f, lower = l, upper = upper1)$value - 1
      root <- uniroot(target_fun, interval = c(-100, upper1 - 1e-6))
      lower1 <- root$root
    } else if (find_bound == "upper") {
      # 已知lower1,找upper使得积分从lower1到upper=1
      target_fun <- function(u) integrate(f, lower = lower1, upper = u)$value - 1
      root <- uniroot(target_fun, interval = c(lower1 + 1e-6, 100))
      upper1 <- root$root
    }
  }
  
  # 确定积分区间
  if (uppertail) {
    lower <- upper1
    upper <- lower1
  } else {
    lower <- lower1
    upper <- upper1
  }
  
  # 计算各阶矩
  m0f <- integrate(f, lower = lower, upper = upper)
  m1f <- integrate(xf, lower = lower, upper = upper)
  m2f <- integrate(xxf, lower = lower, upper = upper)
  
  # 计算方差
  variance <- m2f$value - (m1f$value)^2
  
  # 计算中位数
  median_fun <- function(x) {
    if (uppertail) {
      integrate(f, lower = x, upper = lower)$value - 0.5
    } else {
      integrate(f, lower = lower, upper = x)$value - 0.5
    }
  }
  median_root <- uniroot(median_fun, interval = c(lower, upper))
  median_val <- median_root$root
  
  # 返回结果列表
  return(list(
    integral = m0f$value,
    mean = m1f$value,
    variance = variance,
    median = median_val,
    interval = c(lower, upper)
  ))
}

3. 测试示例

以f(x)=x为例验证:

  1. 给定lower=0,自动找upper使积分=1:
result <- dense(lower1 = 0, find_bound = "upper", f = function(x) x)
print(result)

输出结果符合纸笔计算:积分值为1,均值≈0.6667,方差≈0.0556,中位数≈1.4142。

  1. 指定区间直接计算:
result2 <- dense(lower1 = 0, upper1 = sqrt(2), f = function(x) x)
print(result2)

同样得到正确结果。

内容的提问来源于stack exchange,提问作者Nabil

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 23:12:46