如何使用ggplot2的geom_density()对比不同国家水果数据集的密度分布
问题原因说明
geom_density()返回的density是概率密度值,满足「曲线下面积积分=1」的规则,而非「所有离散采样点的密度值求和=1」。你直接对提取的离散密度列求和时没有乘x轴采样步长,因此得到的结果不等于1。
你观测到的两国苹果密度峰值差异大,是因为两次单独绘图时x轴取值范围不一致,密度曲线为了保证总面积为1会自动调整峰值高度,导致形状相似但峰值无法直接对比。
解决方案
1. 校准提取的密度值到归一化状态
如果需要提取的密度值满足求和为1的要求,两种方法可选:
# 方法1:按积分逻辑校准,结果接近1(符合概率密度的数学定义) x_step <- diff(apple_df$x)[1] # 提取x轴的固定采样间隔 sum(apple_df$density * x_step) # 方法2:直接线性归一化,结果严格为1 apple_df$norm_density <- apple_df$density / sum(apple_df$density) sum(apple_df$norm_density)
2. 实现两国分布对比
最优方案是将两个数据集合并为同一个数据框,新增字段标识国家,用分组映射绘图,ggplot会自动对每组单独做密度归一化,保证每组曲线下面积均为1,可直接对比峰值与分布形状:
# 模拟B国水果重量数据集 set.seed(2345) df_b = data.frame( country = "B国", fruits = factor(rep(c("Orange", "Apple", "Pears", "Banana"), each = 200)), weight = round(c(rnorm(200, mean = 57, sd=5), rnorm(200, mean=67, sd=5), rnorm(200, mean=72, sd=5), rnorm(200, mean=77, sd=5))) ) # 给A国数据集新增标识字段 df$country <- "A国" # 合并两国数据 df_all <- rbind(df, df_b) # 合并绘图,统一坐标系下直接对比两国分布 ggplot(df_all, aes(x = weight, color = country, fill = country)) + geom_density(alpha = 0.3) + # 半透明填充方便查看重叠区域 facet_grid(fruits ~ ., scales = "free", space = "free")
如果不想合并数据集,也可以分别对两国提取的密度做上述归一化处理后,用geom_line()绘制归一化后的密度曲线即可。
内容的提问来源于stack exchange,提问作者Math Avengers
相关产品推荐
相关产品推荐

