【问题标题】:sort columns with categorical variables by numerical varables in stacked barplot按堆积条形图中的数值变量对具有分类变量的列进行排序
【发布时间】:2019-08-30 14:59:01
【问题描述】:

我有一个包含数字(百分比)和分类变量的数据框。我想生成一个堆积条形图(使用 ggplot2),其中列(分类变量)按数值变量排序。

我试过这个:

How to control ordering of stacked bar chart using identity on ggplot2

还有这个:

https://community.rstudio.com/t/a-tidy-way-to-order-stacked-bar-chart-by-fill-subset/5134

但我对因子不熟悉,想了解更多。

# Reproduce a dummy dataset
perc <- c(11.89, 88.11, 2.56, 97.44, 5.96, 94.04, 6.74, 93.26)
names <- c('A', 'A', 'B', 'B', 'C', 'C', 'D', 'D')

df <- data.frame(class = rep(c(-1, 1), 4), 
                 percentage = perc, 
                 name = names)

# Plot
ggplot(df, aes(x = factor(name), y = percentage, fill = factor(class))) +
  geom_bar(stat = "identity") +
  scale_fill_discrete(name = "Class") +
  xlab('Names')

此代码生成一个图,其条形按变量“名称”排序。我想按变量“百分比”对其进行排序。即使我手动订购数据框,结果图也是一样的。

【问题讨论】:

    标签: r ggplot2


    【解决方案1】:

    在绘图之前更改关卡将为您完成。

    lvlorder = order((df[df$class==-1,])$百分比,递减 = T)

    df$name = factor(df$name, levels = levels(df$name)[lvlorder])

    【讨论】:

      【解决方案2】:

      这里的问题是,给定类别 (name) 的所有百分比实际上加起来是 100%。所以按百分比排序(通常通过aes(x = reorder(name, percentage), y = percentage) 实现)在这里不起作用。

      相反,您可能希望按具有 class= 1(或 class= -1)的数据的百分比进行排序。这样做需要一些技巧:使用ifelse 选择class == 1 所在行的百分比。对于所有其他行,选择值 0:

      ggplot(df, aes(x = reorder(name, ifelse(class == 1, percentage, 0)), y = percentage, fill = factor(class))) +
        geom_bar(stat = "identity") +
        scale_fill_discrete(name = "Class") +
        xlab('Names')
      

      您可能只想执行reorder 指令以查看发生了什么:

      reorder(df$name, ifelse(df$class == 1, df$percentage, 0))
      # [1] A A B B C C D D
      # attr(,"scores")
      #      A      B      C      D
      # 44.055 48.720 47.020 46.630
      # Levels: A D C B
      

      如您所见,您的姓名已根据每个类别的平均百分比重新排序(默认情况下,reorder 使用平均值;see its manual page for more details)。但是我们计算的“平均值”在每个名称的百分比之间,即 class= 1 和值 0(对于类 ≠ 1)。

      【讨论】:

        【解决方案3】:

        它类似于Konrad Rudolph,我刚刚创建了一个因子级别并使用它来重新排序。这是我的解决方案:

        x_order <- with(subset(df, class == -1), reorder(name, percentage))
        df$name <- factor(df$name, levels = levels(x_order))
        ggplot(df, aes(x = name,  y = percentage, fill = factor(class))) +
          geom_bar(stat = "identity") +
          scale_x_discrete(breaks = levels(x_order))
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-09-21
          • 1970-01-01
          • 2018-12-21
          • 1970-01-01
          • 2017-05-28
          • 2018-01-07
          相关资源
          最近更新 更多