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

在R语言ggplot中同时按频率与字母顺序重排条形图

解决ggplot条形图按频率降序+同频率正字母排序的问题

需求说明

需要实现条形图的双重排序规则:

  • 优先按频率(Abs_fam.Freq)降序排列
  • 频率相同的类别,按名称(Abs_fam.Var1)正字母顺序排列

当前使用reorder(Abs_fam.Var1, Abs_fam.Freq)仅能实现频率排序,但同频率类别会呈现逆字母顺序,不符合期望。

当前输出与期望输出

当前输出(同频率逆字母):

G - 60
T - 50
C - 40
B - 40
A - 40

期望输出(同频率正字母):

G - 60
T - 50
A - 40
B - 40
C - 40

示例数据与现有代码

示例数据

fam_sub <- structure(
  list(
    Abs_fam.Var1 = c(
      "Apio",
      "Myria",
      "Xyla",
      "Rhyti",
      "Hypo",
      "Phaci"
    ),
    Abs_fam.Freq = c(1L, 1L, 1L, 2L, 8L, 53L)
  ),
  row.names = c(NA,-6L),
  groups = structure(
    list(
      Abs_fam.Freq = c(1L, 2L, 8L, 53L),
      .rows = structure(
        list(1:3, 4L, 5L, 6L),
        ptype = integer(0),
        class = c("vctrs_list_of",
                  "vctrs_vctr", "list")
      )
    ),
    class = c("tbl_df", "tbl", "data.frame"),
    row.names = c(NA,-4L),
    .drop = TRUE
  ),
  class = c("grouped_df",
            "tbl_df", "tbl", "data.frame"))

现有绘图代码

library(ggplot2)

ggplot(fam_sub, aes(x = reorder(Abs_fam.Var1, Abs_fam.Freq), y = Abs_fam.Freq)) +
  geom_col(fill = "#559355") +
  coord_flip() +
  theme_minimal()

解决方案

推荐先手动处理数据的因子水平,再绘图,逻辑更清晰易维护:

library(ggplot2)
library(dplyr)

# 1. 取消数据分组,按规则排序后定义因子水平
fam_sub_sorted <- fam_sub %>%
  ungroup() %>%
  # 先按频率降序,再按名称正字母排序
  arrange(desc(Abs_fam.Freq), Abs_fam.Var1) %>%
  # 将名称转为因子,水平顺序为排序后的结果
  mutate(Abs_fam.Var1 = factor(Abs_fam.Var1, levels = Abs_fam.Var1))

# 2. 绘图
ggplot(fam_sub_sorted, aes(x = Abs_fam.Var1, y = Abs_fam.Freq)) +
  geom_col(fill = "#559355") +
  coord_flip() +
  theme_minimal()

如果不想提前处理数据,也可以直接在aes()中用自定义规则的reorder():

library(ggplot2)
library(dplyr)

ggplot(fam_sub %>% ungroup(), 
       aes(x = reorder(Abs_fam.Var1, 
                       # 先按负频率实现降序,再按名称正序微调排序值
                       -Abs_fam.Freq + as.integer(factor(Abs_fam.Var1))/1000), 
           y = Abs_fam.Freq)) +
  geom_col(fill = "#559355") +
  coord_flip() +
  theme_minimal()

原理说明

默认reorder()函数在排序变量值相同时,会保留原因子水平的逆序排列。通过手动定义因子水平,或在排序值中加入基于名称字母顺序的微小偏移,就能让同频率类别按正字母顺序排列。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 17:13:30