【问题标题】:Order discrete x scale by frequency/value按频率/值排序离散 x 比例
【发布时间】:2011-03-16 06:46:17
【问题描述】:

我正在使用带有离散 x 刻度的 ggplot 制作一个闪避的条形图,x 轴现在按字母顺序排列,但我需要重新排列它,以便它按 y 轴的值排序(即最高的条将位于左侧)。

我尝试了 order 或 sort,但结果是 x 轴排序,而不是条形。

我做错了什么?

【问题讨论】:

    标签: r ggplot2 r-faq


    【解决方案1】:

    @Yuriy Petrovskiy's answer 如果您事先知道要绘制的级别,那就太好了。如果您不这样做(例如,因为您不想绘制数据中不存在的级别),请考虑使用 limit 函数 来指定顺序:

    library(ggplot2)
    
    my_order <- as.character(c(8,3,4,5,6))    # the `as.character` calls are only
    ggplot(mtcars, aes(as.character(cyl))) +  # necessary for the OP's example
      geom_bar() +
      scale_x_discrete(limits = function(x) my_order[my_order %in% x])
    

    来自scale_x_discrete的文档:

    limits
    其中之一:
    - NULL 使用默认比例值
    - 定义比例的可能值及其顺序的字符向量
    - 接受现有(自动)值并返回新值的函数

    否则你的图表会变成这样(可能更可取):

    ggplot(mtcars, aes(as.character(cyl))) +
      geom_bar() +
      scale_x_discrete(limits = my_order)
    

    【讨论】:

      【解决方案2】:

      对我来说最好的方法是使用带有类别的向量,以便我需要将limits 参数作为scale_x_discrete 的参数。我认为这是非常简单明了的解决方案。

      ggplot(mtcars, aes(factor(cyl))) + 
        geom_bar() + 
        scale_x_discrete(limits=c(8,4,6))
      

      【讨论】:

      • @HendyIrawan 没有图例,除非您将其他维度(颜色、填充)也映射到同一个变量。
      • 我认为这是最好的答案。它控制 x 轴值的顺序,不会转换或影响数据框。 factorreorder 的使用改变了数据的特征,尽管是在 ggplot() 调用中,因此对于手头的问题所做的超出了它的需要。
      • 这应该是公认的答案!!为什么要通过编写 2 到 3 行代码来完成您可以在一行优雅(预定义)的代码中完成的事情?
      • 这也适用于我按 y 的值订购 x:scale_x_discrete(limits = DT$x[order(-DT$y)])+
      • 如果您想指定所有可能级别的顺序,但不希望未使用的级别最终出现在您的绘图中,请查看my answer below
      【解决方案3】:

      Hadley 一直在开发一个名为 forcats 的包。这个包使任务变得更加容易。当你想通过一个因子的频率改变x轴的顺序时,你可以利用fct_infreq()。对于本文中的mtcars 示例,您希望按每个级别的频率对cyl 的级别进行重新排序。最常出现的级别停留在左侧。您只需要fct_infreq()

      library(ggplot2)
      library(forcats)
      
      ggplot(mtcars, aes(fct_infreq(factor(cyl)))) +
      geom_bar() +
      labs(x = "cyl")
      

      如果你想反过来,你可以使用fct_rev()fct_infreq()

      ggplot(mtcars, aes(fct_rev(fct_infreq(factor(cyl))))) +
      geom_bar() +
      labs(x = "cyl") 
      

      【讨论】:

        【解决方案4】:

        尝试在 x 轴上手动设置因子的水平。例如:

        library(ggplot2)
        # Automatic levels
        ggplot(mtcars, aes(factor(cyl))) + geom_bar()    
        

        # Manual levels
        cyl_table <- table(mtcars$cyl)
        cyl_levels <- names(cyl_table)[order(cyl_table)]
        mtcars$cyl2 <- factor(mtcars$cyl, levels = cyl_levels)
        # Just to be clear, the above line is no different than:
        # mtcars$cyl2 <- factor(mtcars$cyl, levels = c("6","4","8"))
        # You can manually set the levels in whatever order you please. 
        ggplot(mtcars, aes(cyl2)) + geom_bar()
        

        正如 James 在他的回答中指出的那样,reorder 是重新排序因子水平的惯用方式。

        mtcars$cyl3 <- with(mtcars, reorder(cyl, cyl, function(x) -length(x)))
        ggplot(mtcars, aes(cyl3)) + geom_bar()
        

        【讨论】:

          【解决方案5】:

          我意识到这是旧的,但也许我创建的这个功能对那里的人有用:

          order_axis<-function(data, axis, column)
          {
            # for interactivity with ggplot2
            arguments <- as.list(match.call())
            col <- eval(arguments$column, data)
            ax <- eval(arguments$axis, data)
          
            # evaluated factors
            a<-reorder(with(data, ax), 
                       with(data, col))
          
            #new_data
            df<-cbind.data.frame(data)
            # define new var
            within(df, 
                   do.call("<-",list(paste0(as.character(arguments$axis),"_o"), a)))
          }
          

          现在,您可以使用此功能与 ggplot2 交互绘图,如下所示:

          ggplot(order_axis(df, AXIS_X, COLUMN_Y), 
                 aes(x = AXIS_X_o, y = COLUMN_Y)) +
                  geom_bar(stat = "identity")
          

          可以看出,order_axis 函数创建了另一个数据框,其中包含一个名称相同但末尾带有 _o 的新列。这个新列的级别按升序排列,因此 ggplot2 会自动按该顺序绘制。

          这有点有限(仅适用于字符或因子以及列的数字组合并按升序排列)但我仍然发现它对于在旅途中绘图非常有用。

          【讨论】:

          • 我想我没有看到与直接使用reorder 相比的优势。 ggplot(df, aes(x = reorder(AXIS_X, COLUMN_Y), y = COLUMN_Y)) + ... 不做同样的事情吗?同样简洁,没有辅助函数?
          【解决方案6】:

          你可以使用reorder:

          qplot(reorder(factor(cyl),factor(cyl),length),data=mtcars,geom="bar")
          

          编辑:

          要让最高的酒吧在左边,你必须使用一点杂牌:

          qplot(reorder(factor(cyl),factor(cyl),function(x) length(x)*-1),
             data=mtcars,geom="bar")
          

          我希望它也有负高度,但它没有,所以它有效!

          【讨论】:

          • 我很震惊这个答案没有更多的支持,90% 的时间这是正确的方法。
          • 我认为这两个因素调用都是多余的。第一个参数隐含调用 factor,第二个参数假定为数字。
          • 帮助我弄清楚这些解决方案在幕后做了什么的解释:rstudio-pubs-static.s3.amazonaws.com/…
          • desc(reorder(.)) 可以给你左边最高的条。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2017-11-05
          • 2016-06-30
          • 2014-11-07
          • 1970-01-01
          • 1970-01-01
          • 2016-08-27
          • 1970-01-01
          相关资源
          最近更新 更多