如何绘制按n值排序且带分面(facet)的有序条形图?
分面条形图单词未按n值排序的问题排查与解决
你现在遇到的问题是:想绘制按u_c分面、每个分面内单词按n值排序的条形图,但当前代码里的单词没有按预期排序。咱们来一步步拆解问题:
问题出在哪?
你用了mutate(word = reorder(word, n)),但这里的reorder()是全局计算每个单词的排序依据(默认取该单词所有n值的中位数),而不是在每个u_c分面内单独排序。比如apples在candidate组的n是0.567,在user组是0.274,reorder()会把这两个值的中位数作为apples的排序依据,导致它在两个分面里的位置是固定的,而不是各自分面内按n从大到小排。
解决方法
要实现分面内按n值排序,我们需要让排序逻辑跟着每个u_c分组走,这里有两种简单的实现方式:
方法1:提前分组处理排序
先按u_c分组,给每个组内的word按n值重新排序,再转换成因子:
library(tidyverse) d %>% group_by(u_c) %>% mutate(word = fct_reorder(word, n, .desc = TRUE)) %>% # 组内按n降序排序 ungroup() %>% ggplot(aes(word, n, fill = u_c)) + geom_col(show.legend = FALSE) + facet_wrap(~u_c, scales = "free_y") + coord_flip()
方法2:在ggplot中直接指定分组排序
不用提前处理数据,直接在aes中用fct_reorder并设置.by_group = TRUE,让排序跟随分面的分组逻辑:
d %>% ggplot(aes(fct_reorder(word, n, .desc = TRUE, .by_group = TRUE), n, fill = u_c)) + geom_col(show.legend = FALSE) + facet_wrap(~u_c, scales = "free_y") + coord_flip() + labs(x = "word") # 把x轴标签改回word
这两种方法都能让每个分面里的单词按该分面内的n值从大到小排列,符合你想要的效果。
验证用的数据
你提供的数据dput如下:
d <- structure(list(word = c("apples", "apples", "melon", "curcuma", "banana", "kiwi", "grape", "curcuma", "grape", "wood", "satsuma", "melon", "raisin", "papaya", "plum", "plum", "papaya", "banana", "satsuma", "peach"), u_c = c("candidate", "user", "user", "candidate", "user", "candidate", "user", "user", "candidate", "user", "user", "candidate", "user", "candidate", "candidate", "user", "user", "candidate", "candidate", "candidate" ), n = c(0.56704584625991, 0.273789875549109, 0.190633674260422, 0.105308514305412, 0.0914084706627656, 0.0565322302654257, 0.0562029558128485, 0.0547338017954938, 0.0498104102033781, 0.0439600056682254, 0.0393399851625864, 0.0380903136849362, 0.0370685271783074, 0.0370561875215443, 0.035849706997587, 0.0352763676677753, 0.0325506180866405, 0.0206825232678387, 0.0198207514650121, 0.0113753877973113)), class = c("tbl_df", "tbl", "data.frame" ), row.names = c(NA, -20L))
内容的提问来源于stack exchange,提问作者Tito Sanz
相关产品推荐
相关产品推荐

