如何在for循环中按计数对geom_bar()的条形进行降序重排?
问题描述
现有如下样本数据:
df <- structure(list(Gender = structure(c(3L, 1L, 3L, 1L, 3L, 3L, 1L, 3L, 1L, 3L, 1L), levels = c("Man", "Other", "Woman"), class = "factor"), Country = structure(c(2L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L), levels = c("Germany", "Poland"), class = "factor")), row.names = c(NA, -11L), class = c("tbl_df", "tbl", "data.frame"))
使用以下for循环为每个变量生成条形图:
library(ggplot2) for (i in colnames(df)){ plot <- ggplot(data = df, aes_string(y = i)) + geom_bar() print(plot) }
代码可正常生成2个条形图,但希望将条形按计数降序排列。在循环外可通过reorder()、fct_reorder()或fct_infreq()实现,但在循环中尝试这些方法无效,寻求解决办法,可使用geom_bar()或geom_col()。
解决方案
方法1:用fct_infreq()在循环内重排因子水平
fct_infreq()可直接按因子出现频率降序排列,在aes_string中直接处理变量即可:
library(ggplot2) library(forcats) for (i in colnames(df)){ plot <- ggplot(data = df, aes_string(y = "fct_infreq(.data[[i]])")) + geom_bar() + labs(y = i) # 还原原变量名作为y轴标题 print(plot) }
通过labs(y = i)将y轴标题改回原变量名,避免显示函数表达式。
方法2:用reorder()配合统计值排序
如果不想加载forcats包,可使用reorder()结合geom_bar的内置统计值实现排序:
library(ggplot2) for (i in colnames(df)){ plot <- ggplot(data = df, aes(x = reorder(!!sym(i), ..count.., FUN = function(x) -sum(x)), y = ..count..)) + geom_bar() + coord_flip() + # 保持原图表的横向条形样式 labs(y = "计数", x = i) print(plot) }
用!!sym(i)将字符串变量转换为符号,配合..count..统计值实现降序,最后通过coord_flip()还原横向条形布局。
方法3:先统计计数再用geom_col()
先对每个变量的类别计数进行统计排序,再基于统计结果绘图,逻辑更直观:
library(ggplot2) library(dplyr) for (i in colnames(df)){ # 统计每个类别计数并按降序排列 count_df <- df %>% count(!!sym(i), name = "count") %>% arrange(desc(count)) plot <- ggplot(count_df, aes(x = count, y = !!sym(i))) + geom_col() + labs(y = i, x = "计数") print(plot) }
这种方式先生成包含计数的数据集,直接基于排序后的结果绘图,便于后续样式调整。
内容的提问来源于stack exchange,提问作者johnjohn
相关产品推荐
相关产品推荐

