R 如何在ggplot中按比例有效地重新排序因子?

R 如何在ggplot中按比例有效地重新排序因子?,r,ggplot2,dplyr,R,Ggplot2,Dplyr,我的问题是,我想对使用geom_bar(position=“fill”)生成的ggplot输出中的因子进行重新排序,以便正类的最高比例最接近y轴。我设法找到了一个有效的解决方案,但从我的研究来看,似乎有一个更有效的解决方案潜伏着,尽管我似乎找不到它 我已经通读了这个问题,但我似乎找不到按比例排序的解决方案,也就是说,按数据框中没有明确显示的值排序,但这是一个汇总统计 我已经看过了,并提出了一个解决方案,即使用fct\u reorder2()从这些值创建一个带有“prop”列和线图的摘要数据框。然

我的问题是,我想对使用
geom_bar(position=“fill”
)生成的ggplot输出中的因子进行重新排序,以便正类的最高比例最接近y轴。我设法找到了一个有效的解决方案,但从我的研究来看,似乎有一个更有效的解决方案潜伏着,尽管我似乎找不到它

我已经通读了这个问题,但我似乎找不到按比例排序的解决方案,也就是说,按数据框中没有明确显示的值排序,但这是一个汇总统计

我已经看过了,并提出了一个解决方案,即使用
fct\u reorder2()
从这些值创建一个带有“prop”列和线图的摘要数据框。然而,我似乎无法将类似的逻辑应用于“填充”条形图

我最终偶然发现的解决方案来自此源代码,您只需使用
mutate()
设置新的因子级别。然而,我并没有自己定义顺序,而是创建了一个数据框架,按照正类的比例对因子进行排序

我想知道的是,是否有一种更有效的方法可以做到这一点,也许是在一个长管道操作中

下面是一个可复制的示例:

library(ggplot2)
library(dplyr)

variable <- c(rep("alpha", 4),
              rep("beta", 4),
              rep("gamma", 4),
              rep("delta", 4))

class <- c(rep("1", 4),
           "1", "1", "0", "0",
           rep("0", 3), "1",
           rep("1", 3), "0")

dframe <- data.frame(variable, class)

plot_order <- dframe %>%
  count(variable, class) %>%
  group_by(variable) %>%
  mutate(prop = prop.table(n)) %>%
  filter(class == "1") %>%
  arrange(prop)

lvls <- as.character(plot_order$variable)

dframe %>%
  mutate(variable = factor(variable, levels = lvls)) %>%
  ggplot(aes(x = variable, fill = class)) +
  geom_bar(position ="fill") +
  labs(y = "Proportion")
结果是:

基于位置“填充”的有序因子条形图


提前感谢。

您可以使用
forcats
软件包中的
fct\u-reorder
。在您链接的第一个问题中也多次提到此包:

# data
dframe <- data.frame(
  variable = rep(c("alpha", "beta", "gamma", "delta"), each = 4),
  class = c(rep("1", 4),
            "1", "1", "0", "0",
            rep("0", 3), "1",
            rep("1", 3), "0"))

dframe %>%
  # convert variable to a factor, ordered (in descending order) by the proportion of
  # rows where the class == "1"
  mutate(variable = forcats::fct_reorder(.f = variable, 
                                         .x = class,
                                         .fun = function(.x) mean(.x == "1"),
                                         .desc = TRUE)) %>%
  ggplot(aes(x = variable, fill = class)) +
  geom_bar(position = "fill") +
  labs(y = "Proportion")
#数据
数据帧%
#将变量转换为因子,按下列比例排序(降序):
#类==“1”所在的行
mutate(variable=forcats::fct_reorder(.f=variable,
.x=类,
.fun=函数(.x)平均值(.x==“1”),
.desc=TRUE))%>%
ggplot(aes(x=变量,fill=类别))+
几何钢筋(位置=“填充”)+
实验室(y=“比例”)

感谢@JJlqbal的编辑。为了补充我的问题,也许有一个解决方案,通过访问geom的内部数据帧?如在
geom_histogram()
中,您可以访问
.count..
.density..
。这是否回答了您的问题?
# data
dframe <- data.frame(
  variable = rep(c("alpha", "beta", "gamma", "delta"), each = 4),
  class = c(rep("1", 4),
            "1", "1", "0", "0",
            rep("0", 3), "1",
            rep("1", 3), "0"))

dframe %>%
  # convert variable to a factor, ordered (in descending order) by the proportion of
  # rows where the class == "1"
  mutate(variable = forcats::fct_reorder(.f = variable, 
                                         .x = class,
                                         .fun = function(.x) mean(.x == "1"),
                                         .desc = TRUE)) %>%
  ggplot(aes(x = variable, fill = class)) +
  geom_bar(position = "fill") +
  labs(y = "Proportion")