R ggplot2频率直方图加正态曲线及与SPSS结果差异求解
SPSS与R直方图差异及频率直方图叠加正态曲线解决方案
1. SPSS和R绘制直方图的底层逻辑差异
- 分箱规则不同:SPSS默认会根据变量的取值范围自动生成分箱,分箱数量通常为5-15个,分箱起始点默认对齐整数位;你当前代码手动设置了宽度为1的分箱,如果SPSS输出的直方图分箱宽度不是1,或者分箱起始点不同,柱子高度就会出现明显差异,对照SPSS的分箱边界调整
geom_histogram的breaks参数即可对齐样式。 - 边界值归属规则细微差异:两者默认都采用左开右闭的区间规则,但如果分箱边界刚好和数据取值重合时,偶尔会出现边界值归属的差异,可通过
geom_histogram的boundary参数调整分箱边界对齐SPSS规则。 - 样式默认值不同:SPSS默认的填充色、边框样式、坐标轴范围和R的默认配置不同,你当前代码已经手动设置了相关样式参数,对齐参数后即可完全匹配SPSS的输出样式。
2. 频率直方图叠加正态曲线的实现方法
dnorm函数输出的是概率密度值,默认和频率(计数)轴的量纲不匹配,只需要将密度值乘以总样本量 × 分箱宽度即可对齐量纲,不需要修改y轴为密度。
你原有代码中额外加的plot(density(data$alcohol, bw = 0.05))属于base绘图语法,放在ggplot的链式调用中会额外弹出独立绘图窗口,直接删除即可。
修正后的可运行代码如下:
library(ggplot2) library(readxl) # 读取数据 data <- read_excel("~/Dropbox/My Mac (jmbp.local)/Desktop/Kings College London/2021:2022/Statistics/Week 1 stats/cleandata.xlsx") # 计算所需统计量 mean_alc <- mean(data$alcohol, na.rm = TRUE) sd_alc <- sd(data$alcohol, na.rm = TRUE) sample_n <- length(na.omit(data$alcohol)) bin_width <- 1 # 与你设置的分箱宽度保持一致 p <- ggplot(data = data) + geom_histogram(aes(x = alcohol, y = ..count..), breaks = seq(0, 20, by = bin_width), col = "black", fill = "white") + labs(title = "Alcohol Misuse Score", x = "Alcohol Misuse Score", y = "Frequency") + xlim(c(0, 20)) + ylim(c(0, 20)) + # 修正正态曲线的量纲,适配频率轴 stat_function(fun = function(x) dnorm(x, mean = mean_alc, sd = sd_alc) * sample_n * bin_width, colour = "red", linewidth = 1) p
如果要绘制age变量的直方图,只需要将代码中的alcohol替换为age,重新计算对应统计量即可。
内容的提问来源于stack exchange,提问作者Julia
相关产品推荐
相关产品推荐

