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

ggplot2因子排序失效:自定义排序向量未生效求助

解决ggplot2不遵循自定义顺序绘图的问题

我已经创建了一个指定点图顺序的向量,但使用ggplot2绘图时并未遵循该顺序,求各位建议。

原代码

order <- sav %>%
  filter(Subject == "Food") %>%
  arrange(desc(Percentage)) %>%
  select(Location) %>% 
  unlist() %>%
  unname()

order <- replace(order, c(1, 8), order[c(8, 1)])

sav %>%
  ggplot(aes(x = factor(Location, levels = order), y = Percentage,
             color = Subject))+
  geom_point(data = filter(sav, Location != "IRELAND"),
             size = 4, position = position_dodge(0.5))+
  geom_point(data = filter(sav, Location == "IRELAND"),
             size = 6, position = position_dodge(1))+
  geom_linerange(data = filter(sav, Location == "IRELAND"),
                 aes(ymin = 0, ymax = Percentage), 
                 position = position_dodge(1),
                linetype = "dotdash") + 
  geom_linerange(data = filter(sav, Location != "IRELAND"),
                aes(ymin = 0, ymax = Percentage),
                 position = position_dodge(0.5), linetype = "dotdash") + 
  coord_flip()+
  ggtitle(label = "Increase in inflation (by CPI) in Ireland compared to OECD and other countries in OECD")+
  xlab("Countries --> ") +
  ylab("Increase in CPI by % -->")+
  scale_y_continuous(breaks = round(seq(0, 20, by = 1),1))+
  scale_color_manual(name = "Type of Items", 
                    labels = c("Food", "Total", "Excluding food and energy"),
                    values=c(unname(colorblind_colors[2]), 
                              unname(colorblind_colors[3]), 
                              unname(colorblind_colors[4])))+ 
  theme(panel.grid.major.x = element_line(linewidth =.01, color="black"),
        panel.grid.major.y = element_blank(),
        legend.position = "top"
    )

原绘图输出

原绘图输出

自定义顺序与数据集

> dput(order)
c("IRELAND", "NETHERLANDS", "SPAIN", "OECD", "ITALY", "FRANCE", 
"UNITED STATES", "GERMANY", "CANADA")

> dput(sav)
structure(list(Location = c("CANADA", "CANADA", "FRANCE", "FRANCE", 
"GERMANY", "GERMANY", "IRELAND", "IRELAND", "ITALY", "ITALY", 
"NETHERLANDS", "NETHERLANDS", "SPAIN", "SPAIN", "UNITED STATES", 
"UNITED STATES", "OECD", "OECD", "CANADA", "ITALY", "SPAIN", 
"FRANCE", "IRELAND", "UNITED STATES", "NETHERLANDS", "OECD", 
"GERMANY"), Subject = c("Food", "Total", "Food", "Total", "Food", 
"Total", "Food", "Total", "Food", "Total", "Food", "Total", "Food", 
"Total", "Food", "Total", "Food", "Total", "Total_Minus_Food_Energy", 
"Total_Minus_Food_Energy", "Total_Minus_Food_Energy", "Total_Minus_Food_Energy", 
"Total_Minus_Food_Energy", "Total_Minus_Food_Energy", "Total_Minus_Food_Energy", 
"Total_Minus_Food_Energy", "Total_Minus_Food_Energy"), Frequency = c("Monthly", 
"Monthly", "Monthly", "Monthly", "Monthly", "Monthly", "Monthly", 
"Monthly", "Monthly", "Monthly", "Monthly", "Monthly", "Monthly", 
"Monthly", "Monthly", "Monthly", "Monthly", "Monthly", "Monthly", 
"Monthly", "Monthly", "Monthly", "Monthly", "Monthly", "Monthly", 
"Monthly", "Monthly"), Time = c("2022-12", "2022-12", "2022-12", 
"2022-12", "2022-12", "2022-12", "2022-12", "2022-12", "2022-12", 
"2022-12", "2022-12", "2022-12", "2022-12", "2022-12", "2022-12", 
"2022-12", "2022-12", "2022-12", "2022-12", "2022-12", "2022-12", 
"2022-12", "2022-12", "2022-12", "2022-12", "2022-12", "2022-12"
), Percentage = c(11.02015, 6.319445, 12.86678, 5.850718, 19.75631, 
8.550855, 11.74636, 8.224299, 13.14815, 11.63227, 16.7983, 9.586879, 
15.68565, 5.70769, 11.88275, 6.454401, 15.60381, 9.438622, 5.58275, 
4.469475, 4.442303, 3.36004, 4.999758, 5.707835, 6.034873, 7.221961, 
5.05511)), class = "data.frame", row.names = c(NA, -27L))

问题原因

你在ggplot的aes()里临时将Location转换为因子并指定levels,但后续每个geom_*图层都使用了过滤后的子数据集,这种临时转换无法被所有图层正确继承,导致顺序失效。正确的做法是在预处理阶段就把Location列转换成因子并固定levels,确保整个数据集的顺序统一。

修正后代码

# 生成自定义顺序
order <- sav %>%
  filter(Subject == "Food") %>%
  arrange(desc(Percentage)) %>%
  select(Location) %>% 
  unlist() %>%
  unname()

order <- replace(order, c(1, 8), order[c(8, 1)])

# 预处理数据集:将Location转为因子并指定顺序
sav_fixed <- sav %>%
  mutate(Location = factor(Location, levels = order))

# 绘图
sav_fixed %>%
  ggplot(aes(x = Location, y = Percentage, color = Subject))+
  geom_point(data = filter(sav_fixed, Location != "IRELAND"),
             size = 4, position = position_dodge(0.5))+
  geom_point(data = filter(sav_fixed, Location == "IRELAND"),
             size = 6, position = position_dodge(1))+
  geom_linerange(data = filter(sav_fixed, Location == "IRELAND"),
                 aes(ymin = 0, ymax = Percentage), 
                 position = position_dodge(1),
                linetype = "dotdash") + 
  geom_linerange(data = filter(sav_fixed, Location != "IRELAND"),
                aes(ymin = 0, ymax = Percentage),
                 position = position_dodge(0.5), linetype = "dotdash") + 
  coord_flip()+
  ggtitle(label = "爱尔兰与OECD及其他成员国CPI通胀涨幅对比")+
  xlab("国家 --> ") +
  ylab("CPI涨幅(%) -->")+
  scale_y_continuous(breaks = round(seq(0, 20, by = 1),1))+
  scale_color_manual(name = "品类", 
                    labels = c("食品", "整体", "不含食品和能源"),
                    values=c(unname(colorblind_colors[2]), 
                              unname(colorblind_colors[3]), 
                              unname(colorblind_colors[4])))+ 
  theme(panel.grid.major.x = element_line(linewidth =.01, color="black"),
        panel.grid.major.y = element_blank(),
        legend.position = "top"
    )

说明

  • 预处理时通过mutate()将Location转为因子并绑定自定义levels,确保所有绘图图层都遵循同一顺序
  • 绘图时直接使用转换后的Location列,无需重复在aes()里转换
  • 同时将标题、标签等内容译为中文,提升可读性

内容的提问来源于stack exchange,提问作者Smitesh Patil

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 16:00:59