You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 19:17:09