Change the order of a discrete x scale












116















I am making a dodged bar chart using ggplot with discrete x scale, the x axis are now arranged in alphabetical order, but I need to rearrange it so that it is ordered by the value of the y-axis (i.e., the tallest bar will be positioned on the left).



I tried order or sort, but result in sort the x-axis, but not the bars respectively.



What have I done wrong?










share|improve this question





























    116















    I am making a dodged bar chart using ggplot with discrete x scale, the x axis are now arranged in alphabetical order, but I need to rearrange it so that it is ordered by the value of the y-axis (i.e., the tallest bar will be positioned on the left).



    I tried order or sort, but result in sort the x-axis, but not the bars respectively.



    What have I done wrong?










    share|improve this question



























      116












      116








      116


      47






      I am making a dodged bar chart using ggplot with discrete x scale, the x axis are now arranged in alphabetical order, but I need to rearrange it so that it is ordered by the value of the y-axis (i.e., the tallest bar will be positioned on the left).



      I tried order or sort, but result in sort the x-axis, but not the bars respectively.



      What have I done wrong?










      share|improve this question
















      I am making a dodged bar chart using ggplot with discrete x scale, the x axis are now arranged in alphabetical order, but I need to rearrange it so that it is ordered by the value of the y-axis (i.e., the tallest bar will be positioned on the left).



      I tried order or sort, but result in sort the x-axis, but not the bars respectively.



      What have I done wrong?







      r ggplot2 r-faq






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 21 '18 at 19:24









      Henrik

      42.4k994110




      42.4k994110










      asked Jul 15 '10 at 8:11









      lokheartlokheart

      8,8522573149




      8,8522573149
























          5 Answers
          5






          active

          oldest

          votes


















          94














          Try manually setting the levels of the factor on the x-axis. For example:



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


          ggplot of the cars dataset with factor levels automatically determined



          # 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()


          ggplot of the cars dataset with factor levels reordered manually



          As James pointed out in his answer, reorder is the idiomatic way of reordering factor levels.



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


          ggplot of the cars dataset with factor levels reordered using the reorder function






          share|improve this answer

































            169














            The best way for me was using vector with categories in order I need as limits parameter to scale_x_discrete. I think it is pretty simple and straightforward solution.



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


            enter image description here






            share|improve this answer





















            • 1





              This "works".... but the legend still shows the jumbled orders...

              – Hendy Irawan
              Apr 3 '15 at 13:48






            • 1





              @HendyIrawan there is no legend unless you've got other dimensions (color, fill) also mapped to the same variable.

              – Gregor
              Oct 8 '15 at 23:10








            • 2





              I think this is the best answer. It controls the order of the x-axis values and doesn't transform or affect the data-frame. The use of factor and reorder changes characteristics of the data, albeit within the ggplot() call, and so does more than it need do for the problem at hand.

              – mjandrews
              Nov 22 '18 at 17:38






            • 1





              This should be the accepted answer !! Why complicate things by writing 2 to 3 lines of code for something you can do in a single elegant (predefined) line of code?

              – SilSur
              Mar 26 at 12:47





















            36














            You can use reorder:



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


            Edit:



            To have the tallest bar at the left, you have to use a bit of a kludge:



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


            I would expect this to also have negative heights, but it doesn't, so it works!






            share|improve this answer





















            • 5





              I'm shocked this answer doesn't have more upvotes, 90% of the time this is the proper way to do it.

              – Gregor
              Nov 3 '15 at 2:00






            • 1





              I think both the factor calls are superfluous. There is an implicit call to factor for the first argument and hte second argument is assumed to be numeric.

              – 42-
              Sep 16 '17 at 16:38











            • An explanation that helped me figure out what these solutions were doing under the hood: rstudio-pubs-static.s3.amazonaws.com/…

              – keithpjolley
              Sep 6 '18 at 17:47



















            26














            Hadley has been developing a package called forcats. This package makes the task so much easier. You can exploit fct_infreq() when you want to change the order of x-axis by the frequency of a factor. In the case of the mtcars example in this post, you want to reorder levels of cyl by the frequency of each level. The level which appears most frequently stays on the left side. All you need is the fct_infreq().



            library(ggplot2)
            library(forcats)

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


            If you wanna go the other way around, you can use fct_rev() along with fct_infreq().



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


            enter image description here






            share|improve this answer

































              2














              I realize this is old, but maybe this function I created is useful to someone out there:



              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)))
              }


              Now, with this function you can interactively plot with ggplot2, like this:



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


              As can be seen, the order_axis function creates another dataframe with a new column named the same but with a _oat the end. This new column has levels in ascending order, so ggplot2 automatically plots in that order.



              This is somewhat limited (only works for character or factor and numeric combinations of columns and in ascending order) but I still find it very useful for plotting on the go.






              share|improve this answer
























              • I guess I don't see the advantage of this compared to just using reorder directly. Doesn't ggplot(df, aes(x = reorder(AXIS_X, COLUMN_Y), y = COLUMN_Y)) + ... do the same thing, about as concisely, and without the helper function?

                – Gregor
                Nov 21 '18 at 19:47














              Your Answer






              StackExchange.ifUsing("editor", function () {
              StackExchange.using("externalEditor", function () {
              StackExchange.using("snippets", function () {
              StackExchange.snippets.init();
              });
              });
              }, "code-snippets");

              StackExchange.ready(function() {
              var channelOptions = {
              tags: "".split(" "),
              id: "1"
              };
              initTagRenderer("".split(" "), "".split(" "), channelOptions);

              StackExchange.using("externalEditor", function() {
              // Have to fire editor after snippets, if snippets enabled
              if (StackExchange.settings.snippets.snippetsEnabled) {
              StackExchange.using("snippets", function() {
              createEditor();
              });
              }
              else {
              createEditor();
              }
              });

              function createEditor() {
              StackExchange.prepareEditor({
              heartbeatType: 'answer',
              autoActivateHeartbeat: false,
              convertImagesToLinks: true,
              noModals: true,
              showLowRepImageUploadWarning: true,
              reputationToPostImages: 10,
              bindNavPrevention: true,
              postfix: "",
              imageUploader: {
              brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
              contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
              allowUrls: true
              },
              onDemand: true,
              discardSelector: ".discard-answer"
              ,immediatelyShowMarkdownHelp:true
              });


              }
              });














              draft saved

              draft discarded


















              StackExchange.ready(
              function () {
              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f3253641%2fchange-the-order-of-a-discrete-x-scale%23new-answer', 'question_page');
              }
              );

              Post as a guest















              Required, but never shown

























              5 Answers
              5






              active

              oldest

              votes








              5 Answers
              5






              active

              oldest

              votes









              active

              oldest

              votes






              active

              oldest

              votes









              94














              Try manually setting the levels of the factor on the x-axis. For example:



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


              ggplot of the cars dataset with factor levels automatically determined



              # 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()


              ggplot of the cars dataset with factor levels reordered manually



              As James pointed out in his answer, reorder is the idiomatic way of reordering factor levels.



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


              ggplot of the cars dataset with factor levels reordered using the reorder function






              share|improve this answer






























                94














                Try manually setting the levels of the factor on the x-axis. For example:



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


                ggplot of the cars dataset with factor levels automatically determined



                # 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()


                ggplot of the cars dataset with factor levels reordered manually



                As James pointed out in his answer, reorder is the idiomatic way of reordering factor levels.



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


                ggplot of the cars dataset with factor levels reordered using the reorder function






                share|improve this answer




























                  94












                  94








                  94







                  Try manually setting the levels of the factor on the x-axis. For example:



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


                  ggplot of the cars dataset with factor levels automatically determined



                  # 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()


                  ggplot of the cars dataset with factor levels reordered manually



                  As James pointed out in his answer, reorder is the idiomatic way of reordering factor levels.



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


                  ggplot of the cars dataset with factor levels reordered using the reorder function






                  share|improve this answer















                  Try manually setting the levels of the factor on the x-axis. For example:



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


                  ggplot of the cars dataset with factor levels automatically determined



                  # 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()


                  ggplot of the cars dataset with factor levels reordered manually



                  As James pointed out in his answer, reorder is the idiomatic way of reordering factor levels.



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


                  ggplot of the cars dataset with factor levels reordered using the reorder function







                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited Oct 3 '16 at 6:42

























                  answered Jul 15 '10 at 12:23









                  Richie CottonRichie Cotton

                  81k28189308




                  81k28189308

























                      169














                      The best way for me was using vector with categories in order I need as limits parameter to scale_x_discrete. I think it is pretty simple and straightforward solution.



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


                      enter image description here






                      share|improve this answer





















                      • 1





                        This "works".... but the legend still shows the jumbled orders...

                        – Hendy Irawan
                        Apr 3 '15 at 13:48






                      • 1





                        @HendyIrawan there is no legend unless you've got other dimensions (color, fill) also mapped to the same variable.

                        – Gregor
                        Oct 8 '15 at 23:10








                      • 2





                        I think this is the best answer. It controls the order of the x-axis values and doesn't transform or affect the data-frame. The use of factor and reorder changes characteristics of the data, albeit within the ggplot() call, and so does more than it need do for the problem at hand.

                        – mjandrews
                        Nov 22 '18 at 17:38






                      • 1





                        This should be the accepted answer !! Why complicate things by writing 2 to 3 lines of code for something you can do in a single elegant (predefined) line of code?

                        – SilSur
                        Mar 26 at 12:47


















                      169














                      The best way for me was using vector with categories in order I need as limits parameter to scale_x_discrete. I think it is pretty simple and straightforward solution.



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


                      enter image description here






                      share|improve this answer





















                      • 1





                        This "works".... but the legend still shows the jumbled orders...

                        – Hendy Irawan
                        Apr 3 '15 at 13:48






                      • 1





                        @HendyIrawan there is no legend unless you've got other dimensions (color, fill) also mapped to the same variable.

                        – Gregor
                        Oct 8 '15 at 23:10








                      • 2





                        I think this is the best answer. It controls the order of the x-axis values and doesn't transform or affect the data-frame. The use of factor and reorder changes characteristics of the data, albeit within the ggplot() call, and so does more than it need do for the problem at hand.

                        – mjandrews
                        Nov 22 '18 at 17:38






                      • 1





                        This should be the accepted answer !! Why complicate things by writing 2 to 3 lines of code for something you can do in a single elegant (predefined) line of code?

                        – SilSur
                        Mar 26 at 12:47
















                      169












                      169








                      169







                      The best way for me was using vector with categories in order I need as limits parameter to scale_x_discrete. I think it is pretty simple and straightforward solution.



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


                      enter image description here






                      share|improve this answer















                      The best way for me was using vector with categories in order I need as limits parameter to scale_x_discrete. I think it is pretty simple and straightforward solution.



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


                      enter image description here







                      share|improve this answer














                      share|improve this answer



                      share|improve this answer








                      edited Jul 13 '18 at 9:41









                      Axeman

                      19.3k54559




                      19.3k54559










                      answered Sep 18 '11 at 22:15









                      Yuriy PetrovskiyYuriy Petrovskiy

                      4,56372432




                      4,56372432








                      • 1





                        This "works".... but the legend still shows the jumbled orders...

                        – Hendy Irawan
                        Apr 3 '15 at 13:48






                      • 1





                        @HendyIrawan there is no legend unless you've got other dimensions (color, fill) also mapped to the same variable.

                        – Gregor
                        Oct 8 '15 at 23:10








                      • 2





                        I think this is the best answer. It controls the order of the x-axis values and doesn't transform or affect the data-frame. The use of factor and reorder changes characteristics of the data, albeit within the ggplot() call, and so does more than it need do for the problem at hand.

                        – mjandrews
                        Nov 22 '18 at 17:38






                      • 1





                        This should be the accepted answer !! Why complicate things by writing 2 to 3 lines of code for something you can do in a single elegant (predefined) line of code?

                        – SilSur
                        Mar 26 at 12:47
















                      • 1





                        This "works".... but the legend still shows the jumbled orders...

                        – Hendy Irawan
                        Apr 3 '15 at 13:48






                      • 1





                        @HendyIrawan there is no legend unless you've got other dimensions (color, fill) also mapped to the same variable.

                        – Gregor
                        Oct 8 '15 at 23:10








                      • 2





                        I think this is the best answer. It controls the order of the x-axis values and doesn't transform or affect the data-frame. The use of factor and reorder changes characteristics of the data, albeit within the ggplot() call, and so does more than it need do for the problem at hand.

                        – mjandrews
                        Nov 22 '18 at 17:38






                      • 1





                        This should be the accepted answer !! Why complicate things by writing 2 to 3 lines of code for something you can do in a single elegant (predefined) line of code?

                        – SilSur
                        Mar 26 at 12:47










                      1




                      1





                      This "works".... but the legend still shows the jumbled orders...

                      – Hendy Irawan
                      Apr 3 '15 at 13:48





                      This "works".... but the legend still shows the jumbled orders...

                      – Hendy Irawan
                      Apr 3 '15 at 13:48




                      1




                      1





                      @HendyIrawan there is no legend unless you've got other dimensions (color, fill) also mapped to the same variable.

                      – Gregor
                      Oct 8 '15 at 23:10







                      @HendyIrawan there is no legend unless you've got other dimensions (color, fill) also mapped to the same variable.

                      – Gregor
                      Oct 8 '15 at 23:10






                      2




                      2





                      I think this is the best answer. It controls the order of the x-axis values and doesn't transform or affect the data-frame. The use of factor and reorder changes characteristics of the data, albeit within the ggplot() call, and so does more than it need do for the problem at hand.

                      – mjandrews
                      Nov 22 '18 at 17:38





                      I think this is the best answer. It controls the order of the x-axis values and doesn't transform or affect the data-frame. The use of factor and reorder changes characteristics of the data, albeit within the ggplot() call, and so does more than it need do for the problem at hand.

                      – mjandrews
                      Nov 22 '18 at 17:38




                      1




                      1





                      This should be the accepted answer !! Why complicate things by writing 2 to 3 lines of code for something you can do in a single elegant (predefined) line of code?

                      – SilSur
                      Mar 26 at 12:47







                      This should be the accepted answer !! Why complicate things by writing 2 to 3 lines of code for something you can do in a single elegant (predefined) line of code?

                      – SilSur
                      Mar 26 at 12:47













                      36














                      You can use reorder:



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


                      Edit:



                      To have the tallest bar at the left, you have to use a bit of a kludge:



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


                      I would expect this to also have negative heights, but it doesn't, so it works!






                      share|improve this answer





















                      • 5





                        I'm shocked this answer doesn't have more upvotes, 90% of the time this is the proper way to do it.

                        – Gregor
                        Nov 3 '15 at 2:00






                      • 1





                        I think both the factor calls are superfluous. There is an implicit call to factor for the first argument and hte second argument is assumed to be numeric.

                        – 42-
                        Sep 16 '17 at 16:38











                      • An explanation that helped me figure out what these solutions were doing under the hood: rstudio-pubs-static.s3.amazonaws.com/…

                        – keithpjolley
                        Sep 6 '18 at 17:47
















                      36














                      You can use reorder:



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


                      Edit:



                      To have the tallest bar at the left, you have to use a bit of a kludge:



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


                      I would expect this to also have negative heights, but it doesn't, so it works!






                      share|improve this answer





















                      • 5





                        I'm shocked this answer doesn't have more upvotes, 90% of the time this is the proper way to do it.

                        – Gregor
                        Nov 3 '15 at 2:00






                      • 1





                        I think both the factor calls are superfluous. There is an implicit call to factor for the first argument and hte second argument is assumed to be numeric.

                        – 42-
                        Sep 16 '17 at 16:38











                      • An explanation that helped me figure out what these solutions were doing under the hood: rstudio-pubs-static.s3.amazonaws.com/…

                        – keithpjolley
                        Sep 6 '18 at 17:47














                      36












                      36








                      36







                      You can use reorder:



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


                      Edit:



                      To have the tallest bar at the left, you have to use a bit of a kludge:



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


                      I would expect this to also have negative heights, but it doesn't, so it works!






                      share|improve this answer















                      You can use reorder:



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


                      Edit:



                      To have the tallest bar at the left, you have to use a bit of a kludge:



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


                      I would expect this to also have negative heights, but it doesn't, so it works!







                      share|improve this answer














                      share|improve this answer



                      share|improve this answer








                      edited Jul 15 '10 at 15:20

























                      answered Jul 15 '10 at 14:39









                      JamesJames

                      51.8k10121167




                      51.8k10121167








                      • 5





                        I'm shocked this answer doesn't have more upvotes, 90% of the time this is the proper way to do it.

                        – Gregor
                        Nov 3 '15 at 2:00






                      • 1





                        I think both the factor calls are superfluous. There is an implicit call to factor for the first argument and hte second argument is assumed to be numeric.

                        – 42-
                        Sep 16 '17 at 16:38











                      • An explanation that helped me figure out what these solutions were doing under the hood: rstudio-pubs-static.s3.amazonaws.com/…

                        – keithpjolley
                        Sep 6 '18 at 17:47














                      • 5





                        I'm shocked this answer doesn't have more upvotes, 90% of the time this is the proper way to do it.

                        – Gregor
                        Nov 3 '15 at 2:00






                      • 1





                        I think both the factor calls are superfluous. There is an implicit call to factor for the first argument and hte second argument is assumed to be numeric.

                        – 42-
                        Sep 16 '17 at 16:38











                      • An explanation that helped me figure out what these solutions were doing under the hood: rstudio-pubs-static.s3.amazonaws.com/…

                        – keithpjolley
                        Sep 6 '18 at 17:47








                      5




                      5





                      I'm shocked this answer doesn't have more upvotes, 90% of the time this is the proper way to do it.

                      – Gregor
                      Nov 3 '15 at 2:00





                      I'm shocked this answer doesn't have more upvotes, 90% of the time this is the proper way to do it.

                      – Gregor
                      Nov 3 '15 at 2:00




                      1




                      1





                      I think both the factor calls are superfluous. There is an implicit call to factor for the first argument and hte second argument is assumed to be numeric.

                      – 42-
                      Sep 16 '17 at 16:38





                      I think both the factor calls are superfluous. There is an implicit call to factor for the first argument and hte second argument is assumed to be numeric.

                      – 42-
                      Sep 16 '17 at 16:38













                      An explanation that helped me figure out what these solutions were doing under the hood: rstudio-pubs-static.s3.amazonaws.com/…

                      – keithpjolley
                      Sep 6 '18 at 17:47





                      An explanation that helped me figure out what these solutions were doing under the hood: rstudio-pubs-static.s3.amazonaws.com/…

                      – keithpjolley
                      Sep 6 '18 at 17:47











                      26














                      Hadley has been developing a package called forcats. This package makes the task so much easier. You can exploit fct_infreq() when you want to change the order of x-axis by the frequency of a factor. In the case of the mtcars example in this post, you want to reorder levels of cyl by the frequency of each level. The level which appears most frequently stays on the left side. All you need is the fct_infreq().



                      library(ggplot2)
                      library(forcats)

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


                      If you wanna go the other way around, you can use fct_rev() along with fct_infreq().



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


                      enter image description here






                      share|improve this answer






























                        26














                        Hadley has been developing a package called forcats. This package makes the task so much easier. You can exploit fct_infreq() when you want to change the order of x-axis by the frequency of a factor. In the case of the mtcars example in this post, you want to reorder levels of cyl by the frequency of each level. The level which appears most frequently stays on the left side. All you need is the fct_infreq().



                        library(ggplot2)
                        library(forcats)

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


                        If you wanna go the other way around, you can use fct_rev() along with fct_infreq().



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


                        enter image description here






                        share|improve this answer




























                          26












                          26








                          26







                          Hadley has been developing a package called forcats. This package makes the task so much easier. You can exploit fct_infreq() when you want to change the order of x-axis by the frequency of a factor. In the case of the mtcars example in this post, you want to reorder levels of cyl by the frequency of each level. The level which appears most frequently stays on the left side. All you need is the fct_infreq().



                          library(ggplot2)
                          library(forcats)

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


                          If you wanna go the other way around, you can use fct_rev() along with fct_infreq().



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


                          enter image description here






                          share|improve this answer















                          Hadley has been developing a package called forcats. This package makes the task so much easier. You can exploit fct_infreq() when you want to change the order of x-axis by the frequency of a factor. In the case of the mtcars example in this post, you want to reorder levels of cyl by the frequency of each level. The level which appears most frequently stays on the left side. All you need is the fct_infreq().



                          library(ggplot2)
                          library(forcats)

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


                          If you wanna go the other way around, you can use fct_rev() along with fct_infreq().



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


                          enter image description here







                          share|improve this answer














                          share|improve this answer



                          share|improve this answer








                          edited Dec 22 '16 at 7:06

























                          answered Dec 22 '16 at 6:46









                          jazzurrojazzurro

                          16.5k144763




                          16.5k144763























                              2














                              I realize this is old, but maybe this function I created is useful to someone out there:



                              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)))
                              }


                              Now, with this function you can interactively plot with ggplot2, like this:



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


                              As can be seen, the order_axis function creates another dataframe with a new column named the same but with a _oat the end. This new column has levels in ascending order, so ggplot2 automatically plots in that order.



                              This is somewhat limited (only works for character or factor and numeric combinations of columns and in ascending order) but I still find it very useful for plotting on the go.






                              share|improve this answer
























                              • I guess I don't see the advantage of this compared to just using reorder directly. Doesn't ggplot(df, aes(x = reorder(AXIS_X, COLUMN_Y), y = COLUMN_Y)) + ... do the same thing, about as concisely, and without the helper function?

                                – Gregor
                                Nov 21 '18 at 19:47


















                              2














                              I realize this is old, but maybe this function I created is useful to someone out there:



                              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)))
                              }


                              Now, with this function you can interactively plot with ggplot2, like this:



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


                              As can be seen, the order_axis function creates another dataframe with a new column named the same but with a _oat the end. This new column has levels in ascending order, so ggplot2 automatically plots in that order.



                              This is somewhat limited (only works for character or factor and numeric combinations of columns and in ascending order) but I still find it very useful for plotting on the go.






                              share|improve this answer
























                              • I guess I don't see the advantage of this compared to just using reorder directly. Doesn't ggplot(df, aes(x = reorder(AXIS_X, COLUMN_Y), y = COLUMN_Y)) + ... do the same thing, about as concisely, and without the helper function?

                                – Gregor
                                Nov 21 '18 at 19:47
















                              2












                              2








                              2







                              I realize this is old, but maybe this function I created is useful to someone out there:



                              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)))
                              }


                              Now, with this function you can interactively plot with ggplot2, like this:



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


                              As can be seen, the order_axis function creates another dataframe with a new column named the same but with a _oat the end. This new column has levels in ascending order, so ggplot2 automatically plots in that order.



                              This is somewhat limited (only works for character or factor and numeric combinations of columns and in ascending order) but I still find it very useful for plotting on the go.






                              share|improve this answer













                              I realize this is old, but maybe this function I created is useful to someone out there:



                              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)))
                              }


                              Now, with this function you can interactively plot with ggplot2, like this:



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


                              As can be seen, the order_axis function creates another dataframe with a new column named the same but with a _oat the end. This new column has levels in ascending order, so ggplot2 automatically plots in that order.



                              This is somewhat limited (only works for character or factor and numeric combinations of columns and in ascending order) but I still find it very useful for plotting on the go.







                              share|improve this answer












                              share|improve this answer



                              share|improve this answer










                              answered Oct 8 '15 at 23:00









                              eflores89eflores89

                              313620




                              313620













                              • I guess I don't see the advantage of this compared to just using reorder directly. Doesn't ggplot(df, aes(x = reorder(AXIS_X, COLUMN_Y), y = COLUMN_Y)) + ... do the same thing, about as concisely, and without the helper function?

                                – Gregor
                                Nov 21 '18 at 19:47





















                              • I guess I don't see the advantage of this compared to just using reorder directly. Doesn't ggplot(df, aes(x = reorder(AXIS_X, COLUMN_Y), y = COLUMN_Y)) + ... do the same thing, about as concisely, and without the helper function?

                                – Gregor
                                Nov 21 '18 at 19:47



















                              I guess I don't see the advantage of this compared to just using reorder directly. Doesn't ggplot(df, aes(x = reorder(AXIS_X, COLUMN_Y), y = COLUMN_Y)) + ... do the same thing, about as concisely, and without the helper function?

                              – Gregor
                              Nov 21 '18 at 19:47







                              I guess I don't see the advantage of this compared to just using reorder directly. Doesn't ggplot(df, aes(x = reorder(AXIS_X, COLUMN_Y), y = COLUMN_Y)) + ... do the same thing, about as concisely, and without the helper function?

                              – Gregor
                              Nov 21 '18 at 19:47




















                              draft saved

                              draft discarded




















































                              Thanks for contributing an answer to Stack Overflow!


                              • Please be sure to answer the question. Provide details and share your research!

                              But avoid



                              • Asking for help, clarification, or responding to other answers.

                              • Making statements based on opinion; back them up with references or personal experience.


                              To learn more, see our tips on writing great answers.




                              draft saved


                              draft discarded














                              StackExchange.ready(
                              function () {
                              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f3253641%2fchange-the-order-of-a-discrete-x-scale%23new-answer', 'question_page');
                              }
                              );

                              Post as a guest















                              Required, but never shown





















































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown

































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown







                              Popular posts from this blog

                              Guess what letter conforming each word

                              Port of Spain

                              Run scheduled task as local user group (not BUILTIN)