Search code examples
rggplot2levels

Order x-axis elements in barchart by two columns


I want to make a bar chart (geom_bar) using ggplot2, where id is on the x-axis, and the value in N is on the y-axis. However, I want the x-axis to be ordered first by group and then in descending order of N.

id    N    group
1     1    A
2     2    A
3     1    A
4     5    A
5     2    A
6     3    B
7     15   B
8     4    B
9     15   C
10    1    C

The id column levels would be:

Levels: 4, 2, 5, 3, 1, 7, 8, 6, 9, 10

I was able to reorder the data table in the desired order (except N is ascending) with the following; however, it does not alter the levels of id, which seems to be needed to change the order id is plotted on the x-axis:

dt <- dt[with(dt, order(group, factor(N, order(group)))), ]

Below is a representation of the order I'm looking for.

id    N    group
4     5    A
2     2    A
5     2    A
3     1    A
1     1    A
7     15   B
8     4    B
6     3    B
9     15   C
10    1    C

Solution

  • The key is to arrange the level of the 'id' column.

    id <- 1:10
    N <- c(1,2,1,5,2,3,15,4,15,1)
    group <- c(rep("A", 5), rep("B", 3), rep("C", 2))
    
    df <- data.frame(id, N, group, stringsAsFactors = FALSE)
    
    df$id <- factor(df$id, levels=df$id[order(df$group, -df$N)])
    df
    #   id  N group
    # 1   1  1     A
    # 2   2  2     A
    # 3   3  1     A
    # 4   4  5     A
    # 5   5  2     A
    # 6   6  3     B
    # 7   7 15     B
    # 8   8  4     B
    # 9   9 15     C
    # 10 10  1     C
    df$id
    # [1] 1  2  3  4  5  6  7  8  9  10
    # Levels: 4 2 5 1 3 7 8 6 9 10