1. 問題描述
使用ggplot
繪制柱狀圖時淮野,我們可能需要對柱進(jìn)行排序,例如献幔,我們想探究看電視的平均時長和宗教信仰之間的關(guān)系:
# 生成數(shù)據(jù)
relig_summary <- gss_cat %>%
group_by(relig) %>%
summarise(
age = mean(age, na.rm = TRUE),
tvhours = mean(tvhours, na.rm = TRUE),
n = n()
)
# 繪制
ggplot(relig_summary, aes(tvhours, relig)) + geom_col(width = .7, alpha = .7, color = "black")
Fig.1
由于柱子排布沒有明顯規(guī)律妆毕,所以圖非常難解讀。因此痹届,我們期望對柱子排序進(jìn)行調(diào)整呻待。
由于柱子排序,取決于Y軸上作為因子型變量的宗教順序队腐,所以蚕捉,我們可以調(diào)整relig
的因子順序,也就是該變量的levels
柴淘。
2. 解決方案
2.1 fct_reorder()
使用fct_reorder
命令迫淹,它包含三個參數(shù):
-
f
, 你希望調(diào)整順序的因子 -
x
, 你希望用來調(diào)整順序的依據(jù)(必須是一個和f
等長的vector
) -
fun
, 如果x
包含多個數(shù)值,你希望用何種方式處理他們为严,來對f
進(jìn)行排序(默認(rèn)是median
)敛熬。
使用該函數(shù),我們可以輕松的對柱狀圖按降序排列:
ggplot(relig_summary, aes(tvhours, fct_reorder(relig, tvhours))) +
geom_col(width = .7, alpha = .7, color = "black")
Fig.2
當(dāng)然第股,如果我們想讓上邊的柱子按升序排列应民,只需要在上邊的代碼中加一個負(fù)號-
:
ggplot(relig_summary, aes(tvhours, fct_reorder(relig, - tvhours))) +
geom_col(width = .7, alpha = .7, color = "black")
2.2 fct_relevel()
有時,我們需要將一個特殊的類別移到圖的最前邊作為參照夕吻,例如本案例中诲锹,我們特別想用“沒有信仰”的None
和其他類型進(jìn)行對比,所以需要把None
放在最前面涉馅,這時候可以用fct_relevel()
命令:
# 先排序归园,再把`None`放在因子順序的最后
fct <- fct_reorder(relig_summary$relig, relig_summary$tvhours) %>%
fct_relevel("None", after = length(fct))
# 繪圖
ggplot(relig_summary, aes(tvhours, fct)) +
geom_col(width = .7, alpha = .7, color = "black")
Fig.3
其中fct_relevel("None", after = length(fct))
的含義是將“None”放在第length(fct)
位的后面,也就是第length(fct)-1
的位次控漠,對應(yīng)在圖中蔓倍,就是最上方的位置。
如果想把"None"柱放在圖的最下邊盐捷,只需改寫為after = 0
就可以了偶翅。
2.3 fct_reorder2
有時,我們需要基于兩個變量對某一因子進(jìn)行排序碉渡,特別是在繪制折線圖的時候聚谁,這時可以用到fct_reorder2
命令,讓標(biāo)簽排序更加便于觀察:
# data
chks <- subset(ChickWeight, as.integer(Chick) < 10)
# Note that lines match order in legend
ggplot(chks, aes(Time, weight, colour = fct_reorder2(Chick, Time, weight))) +
geom_point() +
geom_line() +
labs(colour = "Chick")
Fig.4
2.5 fct_infreq() 和 fct_rev()
這兩個命令主要是搭配geom_bar()
進(jìn)行使用的滞诺,同樣是對柱狀圖進(jìn)行排序:
# 升序
increase_plot <-
gss_cat %>%
mutate(marital = marital %>% fct_infreq() %>% fct_infreq()) %>%
ggplot(aes(marital)) +
geom_bar()
# 降序
decrease_plot <-
gss_cat %>%
mutate(marital = marital %>% fct_infreq() %>% fct_rev()) %>%
ggplot(aes(marital)) +
geom_bar()
# 合并
pacman::p_load(cowplot)
plot_grid(increase_plot, decrease_plot, labels = c('fct_infreq', 'fct_rev'), label_size = 12)
Fig.5