ggplot绘制密度图时曲线起始早于实际数据问题求助
问题原因与解决思路
原因
这是geom_density()默认的核密度估计行为导致的:核函数会对数据范围外的区域进行平滑拟合延伸,哪怕该区域没有实际数据点,因此药物B的密度曲线会超出它的最早处方日期(2012-01-31),出现在更早的时间区间。
解决思路
1. 截断密度曲线到数据实际范围
使用stat_density()替代geom_density(),并设置trim = TRUE,这样曲线会被严格截断在每种药物的实际日期范围两端,不会延伸到无数据区域:
drugs %>% ggplot(aes(x=date, fill=drug_name, colour=drug_name)) + stat_density(alpha=0.5, geom="area", trim=TRUE) + theme_minimal()+ scale_x_date(date_breaks = "1 year", date_labels = "%Y")+ labs(x = "Years", y = "Density")
2. 限制x轴显示范围
直接通过scale_x_date()的limits参数设定x轴的最小/最大值,或者过滤数据只保留每种药物自身的有效日期区间:
# 方法A:设置x轴范围 drugs %>% ggplot(aes(x=date, fill=drug_name, colour=drug_name)) + geom_density(alpha=0.5)+ theme_minimal()+ scale_x_date(date_breaks = "1 year", date_labels = "%Y", limits = as.Date(c("2003-11-04", NA))) + # 保留药物A的起始日期,右侧不限制 labs(x = "Years", y = "Density") # 方法B:过滤数据,仅保留每种药物自身的有效日期 drugs %>% group_by(drug_name) %>% filter(date >= min(date)) %>% ungroup() %>% ggplot(aes(x=date, fill=drug_name, colour=drug_name)) + geom_density(alpha=0.5)+ theme_minimal()+ scale_x_date(date_breaks = "1 year", date_labels = "%Y")+ labs(x = "Years", y = "Density")
3. 调整核密度带宽
减小带宽参数bw,让密度曲线更贴近实际数据点,减少向外延伸的程度。带宽可以指定具体天数(如bw=30代表30天),或用adjust参数按比例调整默认带宽:
drugs %>% ggplot(aes(x=date, fill=drug_name, colour=drug_name)) + geom_density(alpha=0.5, bw = 30) + # 可根据数据分布调整bw数值 theme_minimal()+ scale_x_date(date_breaks = "1 year", date_labels = "%Y")+ labs(x = "Years", y = "Density")
内容的提问来源于stack exchange,提问作者SpyrosR
相关产品推荐
相关产品推荐

