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

R与ggplot中含数字字符串排序异常:如何实现正确数值顺序?

解决含数字字符串的排序问题

在ggplot中,字符型分类变量默认按字典序排序,因此会出现asq_1, asq_10, asq_11...asq_2的混乱顺序。要让含数字的字符串按数值顺序展示,核心是把变量转换成有序因子,按数字部分的大小指定排序规则。

修改后的完整代码

library(tidyverse)

df = data.frame(x = 1:3)
for (i in 1:15) {
  df[ , paste0("asq_", i)] <- c(0,5,10)
}

df %>% 
  pivot_longer(-x, names_to = "asq_item", values_to = "response") %>%
  # 提取字符串中的数字,转换为整数后排序,将asq_item转为有序因子
  mutate(asq_item = fct_reorder(asq_item, as.integer(str_extract(asq_item, "\\d+")))) %>%
  group_by(asq_item, response) %>%
  summarise(count = n(), .groups = 'drop') %>%
  group_by(asq_item) %>%
  mutate(proportion = count / sum(count)) %>%
  ggplot(aes(x = asq_item, y = proportion, fill = factor(response)))+ 
  geom_bar(stat = "identity", position=position_dodge2(width = 0.9, preserve = "single")) +
  labs(title = "每个ASQ条目下各分类的占比",
       x = "ASQ条目",
       y = "占比",
       fill = "响应值") +
  theme_bw()

关键步骤说明

  • str_extract(asq_item, "\\d+"):从asq_item中提取所有数字字符(比如从asq_12提取"12")
  • as.integer():把提取到的数字字符串转为整数,用于确定排序逻辑
  • fct_reorder(asq_item, ...):将asq_item转换为因子,并按照后面的数值变量排序,这样ggplot的x轴就会按asq_1, asq_2...asq_15的顺序展示。

另一种方法:用gtools::mixedorder指定因子水平

如果你更习惯用gtools包,可以直接把asq_item转为因子,指定水平为mixedorder排序后的结果:

library(gtools)

df_processed <- df %>% 
  pivot_longer(-x, names_to = "asq_item", values_to = "response")

# 指定因子水平为mixedorder排序后的顺序
df_processed$asq_item <- factor(df_processed$asq_item, 
                                levels = df_processed$asq_item[mixedorder(df_processed$asq_item)])

# 后续的统计和绘图代码不变
df_processed %>% 
  group_by(asq_item, response) %>%
  summarise(count = n(), .groups = 'drop') %>%
  group_by(asq_item) %>%
  mutate(proportion = count / sum(count)) %>%
  ggplot(aes(x = asq_item, y = proportion, fill = factor(response)))+ 
  geom_bar(stat = "identity", position=position_dodge2(width = 0.9, preserve = "single")) +
  labs(title = "每个ASQ条目下各分类的占比",
       x = "ASQ条目",
       y = "占比",
       fill = "响应值") +
  theme_bw()

之前用mixedsort没生效,是因为mixedsort只是对向量排序,但如果asq_item还是字符型,ggplot依然会按字典序处理。必须把它转为因子,手动指定排序后的水平才能生效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 16:22:41