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

R语言hist()函数不基于区间宽度计算概率/密度的实现方法

实现基于总元素数的相对频率直方图(忽略区间宽度)

你说得对,R的hist()函数在freq=FALSE时计算的是密度(相对频率除以区间宽度),这和你想要的「每个区间元素数占总元素数的比例」(即相对频率,不考虑区间宽度)不是一回事。因为你的区间长度不一致,默认参数确实满足不了需求,不过我们有两种简便的实现方式,不用完全从零开始写代码:


方法1:利用hist()的统计结果手动计算并绘图

先让hist()帮我们统计每个区间的元素个数,再自己计算相对频率,最后用绘图函数实现你要的效果:

步骤示例

# 你的示例数据和区间
v <- seq(1, 10, 1)
breaks <- c(1, 8, 10)

# 先获取直方图的统计结果,不绘图
h <- hist(v, breaks = breaks, plot = FALSE)

# 计算每个区间的相对频率:区间元素数 / 总元素数
rel_freq <- h$counts / length(v)

# 方式A:用条形图展示(每个条宽度一致,适合强调比例对比)
barplot(rel_freq, 
        names.arg = paste0(h$breaks[-length(h$breaks)], "-", h$breaks[-1]),
        ylab = "Relative Frequency",
        xlab = "Intervals",
        main = "Relative Frequency by Interval")

# 方式B:用矩形绘制「保持区间宽度」的直方图样式
plot(NULL, 
     xlim = range(breaks), 
     ylim = c(0, max(rel_freq) * 1.1), # 留一点顶部空间
     xlab = "Intervals",
     ylab = "Relative Frequency",
     main = "Relative Frequency Histogram (Original Interval Widths)")
# 绘制每个区间的矩形
rect(h$breaks[-length(h$breaks)], 0, 
     h$breaks[-1], rel_freq,
     col = "lightblue")

方法2:自定义一个简单函数封装逻辑

如果需要反复使用,可以把上面的逻辑封装成函数,方便调用:

rel_freq_hist <- function(x, breaks, ...) {
  h <- hist(x, breaks = breaks, plot = FALSE)
  rel_freq <- h$counts / length(x)
  plot(NULL, xlim = range(breaks), ylim = c(0, max(rel_freq)*1.1), ...)
  rect(h$breaks[-length(h$breaks)], 0, h$breaks[-1], rel_freq, ...)
}

# 调用示例
rel_freq_hist(v, breaks = c(1,8,10), 
              xlab = "Intervals", ylab = "Relative Frequency",
              col = "coral", main = "Custom Relative Frequency Histogram")

补充说明

  • 如果你更关注比例的对比,用barplot会更直观,因为它统一了每个类别(区间)的宽度;
  • 如果需要保留原始区间宽度的可视化,用rect绘制的方式更符合直方图的形态,但要注意此时y轴是相对频率,不是密度,所以矩形的面积总和不等于1(这和freq=FALSE的默认行为不同)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 09:45:02