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

ggplot条形图排序异常求助:按egenutfort_fou降序失效

条形图排序失效问题排查

问题现象

使用dplyr的arrange()和head()能正确筛选出egenutfort_fou降序排列的前5条数据:

df %>%
  arrange(desc(egenutfort_fou)) %>%
  head(5)

但将筛选后的数据传入ggplot绘制条形图时,原本的排序却失效了:

df %>%
  arrange(desc(egenutfort_fou)) %>%
  head(5) %>%
  ggplot(aes(x = egenutfort_fou, y = naering)) +
  geom_bar(stat = "identity")

可复现示例数据:

structure(list(naering = c("A03 Fiske, fangst og akvakultur", 
"B05-B09 Bergverksdrift og utvinning", "C10-C11 Næringsmiddel- og drikkevareindustri", 
"C13 Tekstilindustri", "C14-C15 Beklednings-, lær- og lærvareindustri", 
"C16 Trelast- og trevareindustri", "C17 Papir- og papirvareindustri", 
"C18 Trykking, grafisk industri", "C19-C20 Petroleums-, kullvare- og kjemisk industri", 
"C21 Farmasøytisk industri", "C22 Gummivare- og plastindustri", 
"C23 Mineralproduktindustri", "C24 Metallindustri", "C25 Metallvareindustri", 
"C26 Data- og elektronisk industri", "C27 Elektroteknisk industri", 
"C28 Maskinindustri", "C29 Motorkjøretøyindustri", "C30 Transportmiddelindustri ellers", 
"C31 Møbelindustri", "C32 Annen industri", "C33 Reparasjon og installasjon av maskiner og utstyr", 
"D35 Kraftforsyning", "E36-E39 Vann, avløp og renovasjon", "F41-F43 Bygge- og anleggsvirksomhet", 
"G46 Agentur- og engroshandel", "H49-H53 Transport og lagring", 
"J59-J60 Film- og TV-prod., musikkutgivelse, radio- og fjernsynskringkasting", 
"J61 Telekommunikasjon", "J62 IT-tjenester", "J63 Informasjonstjenester", 
"K64-K66 Finansiering og forsikring", "M70 Hovedkontortjen. og adm. rådgivning", 
"M71 Arkitekter og tekniske konsulenter", "M72 Forskning og utviklingsarbeid", 
"M74.9 Annen faglig, vitenskapelig og teknisk virksomhet", "N82.9 Annen forretningsmessig tj.yting"
), egenutfort_fou = c(951.1, 1867.5, 1180, 36.5, 40.9, 205, 145.9, 
66.5, 1718.1, 442.7, 189.9, 152.3, 484.8, 1433.3, 2236.7, 584.6, 
1441.2, 194.5, 402.4, 179.8, 305.1, 316.3, 447.9, 158.2, 352.9, 
838.7, 320.5, 74.8, 714.5, 8090.5, 403.1, 2202.9, 555.8, 2965.2, 
1460, 374.7, 93.7), innkopt_fou = c(201.8, 2054, 178.9, 5.9, 
0, 35.6, 8.8, 2.5, 370.3, 789.7, 23, 40.4, 91.1, 88, 118.3, 22.2, 
61.8, 73.5, 115.5, 14.5, 103.3, 100.9, 23.6, 153.6, NA, 187.9, 
13.4, 248.2, 116.1, 404.4, 220.2, 6, 77, 680.8, 60.1, 525.2, 
53.7), produktinnovasjon = c(94, 65, 441, 42, 22, 100, 13, 61, 
53, 10, 70, 80, 17, 216, 83, 81, 178, 37, 46, 48, 82, 138, 105, 
78, 303, 1308, 142, 112, 70, 984, 124, 217, 281, 730, 119, 235, 
119)), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA, 
-37L))

问题原因

ggplot对分类变量的排序逻辑不受数据框行顺序影响:

  • 如果naering是字符型,ggplot会默认按字母顺序排序
  • 如果是因子型,会按因子的levels顺序排序,而默认因子的levels也是字母顺序

你之前仅调整了数据框的行顺序,但没有改变naering的变量类型或排序规则,所以ggplot会忽略行顺序,重新按默认规则排序。

解决方法

方法1:将naering转换为有序因子

在数据处理阶段,用forcats包的fct_inorder()将naering设置为按当前数据框顺序排列的因子:

library(forcats)

df %>%
  arrange(desc(egenutfort_fou)) %>%
  head(5) %>%
  mutate(naering = fct_inorder(naering)) %>%
  ggplot(aes(x = egenutfort_fou, y = naering)) +
  geom_bar(stat = "identity")

方法2:在ggplot中直接指定排序

无需提前调整数据框顺序,用fct_reorder()直接在aes中指定排序依据:

library(forcats)

df %>%
  head(5) %>%
  ggplot(aes(x = egenutfort_fou, y = fct_reorder(naering, desc(egenutfort_fou)))) +
  geom_bar(stat = "identity")

或者沿用你之前的arrange逻辑,在aes中用fct_inorder():

library(forcats)

df %>%
  arrange(desc(egenutfort_fou)) %>%
  head(5) %>%
  ggplot(aes(x = egenutfort_fou, y = fct_inorder(naering))) +
  geom_bar(stat = "identity")

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 23:25:22