ggplot2小提琴图绘制异常:数据集中于左侧问题排查
问题:小提琴图数据集中在左侧,x轴未按年份分布
我有一个名为masterlist的数据框,合并了2013-2021年的事件统计Excel数据集(比如data2013记录某公司2013年停电次数),数据结构如下:
structure(list(DataYear = c("2013", "2013", "2013", "2013", "2013", "2013"), UtilityNumber = c("97", "108", "155", "162", "195", "207"), UtilityName = c("Adams Electric Coop", "Adams-Columbia Electric Coop", "Agralite Electric Coop", "Aiken Electric Coop Inc", "Alabama Power Co", "City of Alameda"), State = c("IL", "WI", "MN", "SC", "AL", "CA" ), Ownership = c("Cooperative", "Cooperative", "Cooperative", "Cooperative", "Investor Owned", "Municipal"), SAIDIWithMed = c("223", "143", "1142", NA, NA, "16.48"), SAIFIWithMed = c("1.81", "1.093", "3", NA, NA, "6.8000000000000005E-2"), CAIDIWithMed = c("123.20442", "130.83257", "380.66667000000001", NA, NA, "242.35293999999999" ), SAIDIWithoutMed = c("158", "58", "141", NA, NA, NA), SAIFIWithoutMed = c("1.35", "0.69099999999999995", "1", NA, NA, NA), CAIDIWithoutMed = c("117.03704", "83.936323999999999", "141", NA, NA, NA), SAIDIWithMedMinusLOS = c("191", "139", "1134", NA, NA, NA), SAIFIWithMedMinusLOS = c("1.39", "1.028", "2", NA, NA, NA), CAIDIMinusMed = c("137.41006999999999", "135.21401", "567", NA, NA, NA), NumberOfCustomers = c("8715", "36014", "5122", NA, NA, "34347"), OutagesAutomaticallyRecorded = c("N", "Y", "N", NA, NA, "N")), row.names = c(NA, -6L), class = c("tbl_df", "tbl", "data.frame"))
我尝试用以下代码绘制SAIDIWithMed列的小提琴图:
p <- ggplot(masterlist_test, aes(x=DataYear, y=SAIDIWithMed)) + geom_violin() p
但生成的图中所有数据都集中在左侧区域,本该分布在2013至2021的x轴区间内。
问题原因
DataYear是字符型而非有序因子:从数据结构能看到,DataYear的取值是带引号的字符串(如"2013")。ggplot对字符型离散变量默认按字符序排序,若年份未被识别为有序类别,会导致所有数据挤在第一个显示的年份下。SAIDIWithMed是字符型而非数值型:该列的取值也是带引号的字符串(如"223"、"16.48"),ggplot无法对字符型数据进行数值分布统计,这是数据集中在一侧的核心原因——字符型y轴无法正确映射数值的分布规律。
解决步骤
1. 修复数据类型
先把关键列转换成正确的类型:
# 将DataYear转为有序因子,确保年份按2013-2021的顺序排列 masterlist_test$DataYear <- factor(masterlist_test$DataYear, levels = as.character(2013:2021), ordered = TRUE) # 将SAIDIWithMed转为数值型,自动处理NA值 masterlist_test$SAIDIWithMed <- as.numeric(masterlist_test$SAIDIWithMed)
2. 重新绘制小提琴图
library(ggplot2) p <- ggplot(masterlist_test, aes(x=DataYear, y=SAIDIWithMed)) + geom_violin(na.rm = TRUE) # na.rm=TRUE忽略NA值,避免绘图报错 p
3. 可选优化:添加箱线图辅助
如果部分年份数据量较少,小提琴图形态不明显,可以叠加箱线图更清晰展示数据分布:
p <- ggplot(masterlist_test, aes(x=DataYear, y=SAIDIWithMed)) + geom_violin(na.rm = TRUE) + geom_boxplot(width = 0.1, na.rm = TRUE) # 箱线图宽度设小,避免遮挡小提琴图 p
内容的提问来源于stack exchange,提问作者Rohan Buch
相关产品推荐
相关产品推荐

