R语言:如何实现数值向量等距区间划分、统计与绘图?
解决cut()区间问题并实现自定义直方图统计函数
直接放弃依赖cut(),手动生成等距区间是更靠谱的方案——既能精准保留原始的xmin/xmax端点,又能轻松提取区间中点,完美解决你遇到的两个问题。下面是完整的实现代码:
hist_proportion <- function(x, k = NULL) { # 处理k的默认值:取向量长度的1/10,至少为1 if (is.null(k)) { k <- max(1, floor(length(x) / 10)) } # 1. 计算极值(忽略NA) xmin <- min(x, na.rm = TRUE) xmax <- max(x, na.rm = TRUE) # 2. 生成精确的等距区间端点 breaks <- seq(xmin, xmax, length.out = k + 1) # 统计每个区间的元素数量 # findInterval返回每个元素所属的区间索引,tabulate统计各索引的出现次数 counts <- tabulate(findInterval(x, breaks, rightmost.closed = TRUE)) # 计算区间中点 midpoints <- (breaks[-1] + breaks[-length(breaks)]) / 2 # 计算占比 proportions <- counts / length(x) # 3. 绘制图表 plot(midpoints, proportions, type = "h", # 绘制垂直线直方图 lwd = 8, # 线宽调整 xlab = "区间中点", ylab = "元素占比", main = "区间元素占比分布", col = "#3498db") # 可选:添加数据点 points(midpoints, proportions, pch = 16, col = "#e74c3c") # 返回统计结果(可选,方便后续分析) invisible(data.frame( 区间起点 = breaks[-length(breaks)], 区间终点 = breaks[-1], 中点 = midpoints, 元素数量 = counts, 占比 = proportions )) }
为什么这么写?
- 解决区间边缘修改问题:
seq(xmin, xmax, length.out = k+1)直接从原始极值生成等距端点,完全不会像cut()那样自动调整边界。 - 解决区间提取问题:不需要处理
cut()返回的因子字符串,直接通过breaks计算中点,逻辑清晰且高效。 findInterval()比cut()更适合数值统计:它返回的是数值型的区间索引,搭配tabulate()统计数量比table()更简洁,还能通过rightmost.closed = TRUE确保最大值xmax被包含在最后一个区间里。
测试示例
# 生成测试数据 set.seed(123) x <- c(rnorm(80, mean = 5), rnorm(20, mean = 10)) # 调用函数,使用默认k值(100/10=10) result <- hist_proportion(x) # 查看统计结果 print(result)
运行后你会看到:区间端点完全是基于x的真实极值生成的,中点计算准确,图表横轴是区间中点、纵轴是占比,完全符合需求。
内容的提问来源于stack exchange,提问作者user20423494
相关产品推荐
相关产品推荐

