如何在ggplot2中平滑含缺失数据的多折线图断裂线条
解决方案
1. 先把宽格式数据转成适合ggplot的长格式
你的代码重复调用geom_line既繁琐又容易出错,先将数据转换为长格式,后续处理和绘图更高效:
library(dplyr) library(tidyr) # 转换长格式并映射税种名称 df_long <- df_Sweden %>% select(YEAR, CENTAXINCOMESH, CENTAXPROPERTYSH, CENTAXCUSTOMSSH, CENTAXEXCISESH, CENTAXCONSSH) %>% pivot_longer( cols = -YEAR, names_to = "Tax_Type", values_to = "Revenue_Percent" ) %>% mutate( Tax_Type = recode( Tax_Type, "CENTAXINCOMESH" = "Income Taxes", "CENTAXPROPERTYSH" = "Property Taxes", "CENTAXCUSTOMSSH" = "Customs and International Trade", "CENTAXEXCISESH" = "Excise Taxes", "CENTAXCONSSH" = "Consumption Taxes" ) )
2. 用Base R原生工具做线性插值(无需额外下载包)
你提到无法下载spline相关包,用Base R自带的approx()函数就能完成线性插值,关键是按税种分组处理(每个税种的缺失值独立):
# 按税种分组插值缺失值 df_interpolated <- df_long %>% group_by(Tax_Type) %>% mutate( Revenue_Percent = approx( x = YEAR, y = Revenue_Percent, xout = YEAR, method = "linear" # 线性插值,若需阶梯式可改为"constant" )$y ) %>% ungroup()
3. 绘制连续平滑的折线图
用处理好的数据绘图,代码更简洁且符合ggplot最佳实践:
ggplot(df_interpolated, aes(x = YEAR, y = Revenue_Percent, color = Tax_Type, group = Tax_Type)) + geom_line() + scale_y_continuous( limits = c(0, 100), labels = scales::label_percent(scale = 1), expand = expansion(0, 0) ) + scale_x_continuous( n.breaks = 30, limits = c(1890, 2012), expand = c(0, 0) ) + scale_color_manual( values = c( "Income Taxes" = "#991f00", "Property Taxes" = "#ff3300", "Customs and International Trade" = "#00ffff", "Excise Taxes" = "#0099ff", "Consumption Taxes" = "#0000cc" ) ) + theme(axis.text.x = element_text(angle = 45, vjust = 1, hjust = 1)) + labs( x = "Year", y = "% of Government Revenue", color = "Tax Type" ) + theme(plot.title = element_text(hjust = 0.5))
备选方案:直接连接缺失值(不插值)
如果不需要插值,只想让折线跳过缺失值连接前后点,只需在geom_line中添加na.rm = TRUE即可(以原始宽数据为例):
ggplot() + geom_line(data=df_Sweden, aes(x=YEAR, y=CENTAXINCOMESH, color="Income Taxes"), group=1, na.rm=TRUE) + geom_line(data=df_Sweden, aes(x=YEAR, y=CENTAXPROPERTYSH, color="Property Taxes"), group=1, na.rm=TRUE) + geom_line(data=df_Sweden, aes(x=YEAR, y=CENTAXCUSTOMSSH, color="Customs and International Trade"), group=1, na.rm=TRUE) + geom_line(data=df_Sweden, aes(x=YEAR, y=CENTAXEXCISESH, color="Excise Taxes"), group=1, na.rm=TRUE) + geom_line(data=df_Sweden, aes(x=YEAR, y=CENTAXCONSSH, color="Consumption Taxes"), group=1, na.rm=TRUE) + # 其余scale和theme代码保持不变 scale_y_continuous(limits=c(0,100), labels=scales::label_percent(scale=1), expand = expansion(0,0)) + scale_x_continuous(n.breaks = 30, limits = c(1890,2012), expand = c(0, 0)) + scale_color_manual(values=c("Income Taxes" = "#991f00", "Property Taxes" = "#ff3300", "Customs and International Trade" = "#00ffff", "Excise Taxes" = "#0099ff", "Consumption Taxes" = "#0000cc")) + theme(axis.text.x = element_text(angle=45, vjust=1, hjust=1)) + xlab("Year") + ylab("% of Government Revenue") + labs(color="Tax Type") + theme(plot.title=element_text(hjust=0.5))
内容的提问来源于stack exchange,提问作者PhobixPhobix
相关产品推荐
相关产品推荐

