1

I've tried what others have suggested (Order bars in ggplot and Order Bars in ggplot2 bar graph) for ordering columns and I still can't get it.

I have a dataset with a column called "Zap", which has values that I want sorted from the highest occurring count to the least. Here is my R code:

mydata %>% 
  group_by(Zap) %>% 
  summarize(count = n()) %>% 
  mutate(percent = count/sum(count)) %>% 
  ggplot(aes(x=Zap, y=count, fct_infreq(Zap))) +
  xlab("EA5 Zigbee Enabled")+
  geom_col() +
  geom_text(aes(label = paste0(round(100 * percent, 1), "%")), vjust = -0.25)

That code didn't actually reorder anything. This is what I'm getting (not sorted)

enter image description here

I also tried this:

mydata %>% 
  group_by(Zap) %>% 
  summarize(count = n()) %>% 
  mutate(percent = count/sum(count)) %>% 
  ggplot(aes(x=Zap, y=count)) +

  x=reorder(Zap,Zap, function(x)-count(x)) +

  xlab("EA5 Zigbee Enabled")+
  geom_col() +
  geom_text(aes(label = paste0(round(100 * percent, 1), "%")), vjust = -0.25)

But this code gives me an error:

Error in reorder(Zap, Zap, function(x) -count(x)) : object 'Zap' not found

Any ideas what I'm doing wrong?

b-ryce
  • 5,752
  • 7
  • 49
  • 79
  • put the `reorder` line within the `mutate` statement, not in `ggplot` sequence – HubertL Dec 23 '19 at 21:48
  • Thats helpful, but I'm still struggling (I'm very new to R). Here is what I tried: mutate(percent = count/sum(count), x=reorder(Zap,Zap, function(x)-count(x))) %>% But I'm getting "Error in UseMethod("summarise_") : no applicable method for 'summarise_' applied to an object of class "factor"" – b-ryce Dec 23 '19 at 21:56
  • 1
    try `mutate(percent = count/sum(count), Zap = reoder(Zap, count, FUN=identity))` – HubertL Dec 23 '19 at 22:02

3 Answers3

3

You can sort your x variable by their count using reorder(Zap, -count) as the definition of x variables of the aes:

mydata %>% 
  group_by(Zap) %>% 
  summarize(count = n()) %>% 
  mutate(percent = count/sum(count)) %>% 
  ggplot(aes(x=reorder(Zap, -count), y=count, fct_infreq(Zap))) +
  xlab("EA5 Zigbee Enabled")+
  geom_col() +
  geom_text(aes(label = paste0(round(100 * percent, 1), "%")), vjust = -0.25)

enter image description here

Data example

mydata <- data.frame(Zap = c(rep("enabled",85*5),rep("enabled22",1*5),rep("disabled",14*5)))

dc37
  • 15,840
  • 4
  • 15
  • 32
  • is there a way to sort by two variables in using `reorder`. for example `aes(x=reorder(Zap,-count,otherVar)…` this work for me – Derek Krantz Nov 04 '20 at 22:21
1

Here is what I ended up using, thanks to @HubertL for the comment:

mydata %>% 
  group_by(Zap) %>% 
  summarize(count = n()) %>% 
  mutate(percent = count/sum(count), Zap = reorder(Zap, -count, FUN=identity)) %>%
  ggplot(aes(x=Zap, y=count)) +
  xlab("EA5 Zigbee Enabled")+
  geom_col() +
  geom_text(aes(label = paste0(round(100 * percent, 1), "%")), vjust = -0.25)
dc37
  • 15,840
  • 4
  • 15
  • 32
b-ryce
  • 5,752
  • 7
  • 49
  • 79
1

The fct_infreq() function from the forcats package reorders factors by frequency and can be used instead of reorder(). In addition, ggplot2 computes statistics on its own which can be accessed by the stat() function.

So, there is no need to aggregate the data beforehand. Instead, the plot can be created directly from the mydata dataset:

mydata <- data.frame(Zap = rep(c("enabled","enabled.22", "disabled"), 5 * c(85, 1, 14)))

library(ggplot2)

mydata %>% 
  ggplot() +
  aes(x = forcats::fct_infreq(Zap)) +
  geom_bar() + 
  geom_text(aes(y = stat(count), label = sprintf("%.1f%%", 100 * stat(count / sum(count)))), 
            stat = "count", vjust = -0.25) +
  xlab("EA5 Zigbee Enabled")

enter image description here

geom_text() requires to specify the y and label aesthetics which can be derived from the computed statistics using stat().

Uwe
  • 41,420
  • 11
  • 90
  • 134