Home > OS >  How to automate fct_relevel in R?
How to automate fct_relevel in R?

Time:05-22

I'm automating my bar charts and i'm stuck when it comes to order of the items. In my data i'm showing color of sold items. I want it to show 3 best selling colors and others combined. I want the 3 best selling colors to be in order of most soled to the least. And other to be always last. In my mock data i would like to get the following charts.

enter image description here enter image description here

My problem is that i know how to set the order with fct_relevel but how do i automate it that it always relevels it so that other is last and the colors are in the correct order? The colors and the order of colors changes from item to item. I need it to work for any item and color without having to rewrite anything in code.

    DF<- read_xlsx("C:/Users/Desktop/TEST_R.xlsx")


DF <- DF %>%
  filter(Item == "Cars")

DF$Color<- fct_relevel(DF$Color, "Other","Red","Blue","Green") #For Cars
DF$Color<- fct_relevel(DF$Color, "Other","Blue","Black","Red") #For Trucks


ggplot(DF ,aes(y=Color, x=Sales)) 
  geom_bar(stat = 'identity') 
  labs(title=DF$Item) 
  theme_minimal()

My sample data

Item      Color      Sales
Cars      Other      500
Cars      Green      200
Cars      Red         75
Cars      Blue       100
Trucks    Other      150
Trucks    Black       50
Trucks    Red        100
Trucks    Blue        25

Thank you

CodePudding user response:

You could not use fct_relevel and something else entirely

set.seed(1)
cars <- sample(c('Red', 'Green', 'Blue', 'Other'), 100, TRUE)

fct_relevel <- function(x, decreasing = TRUE, other_last = TRUE) {
  lvl <- names(sort(table(x), decreasing = decreasing))
  lvl <- if (other_last)
    c(lvl, 'Other') else c('Other', lvl)
  factor(x, unique(lvl))
}

par(mfrow = c(2, 2))
barplot(table(cars))
barplot(table(fct_relevel(cars, TRUE, TRUE)))
barplot(table(fct_relevel(cars, TRUE, FALSE)))
barplot(table(fct_relevel(cars, FALSE, FALSE)))

enter image description here

CodePudding user response:

Try this ggplot2 approach using reorder_within (to order within item) combined with fct_relevel to place Other last:

(With fct_rev if you need Trucks first. And with geom_col you don't need the stat = "identity")

library(tidyverse)
library(tidytext)

DF <- tribble(
  ~Item, ~Color, ~Sales,
  "Cars", "Other", 500,
  "Cars", "Green", 200,
  "Cars", "Red", 75,
  "Cars", "Blue", 100,
  "Trucks", "Other", 150,
  "Trucks", "Black", 50,
  "Trucks", "Red", 100,
  "Trucks", "Blue", 25
) 

DF %>%
  mutate(
    Color = reorder_within(Color, Sales, Item),
    Color = fct_relevel(Color, "Other___Cars", "Other___Trucks")
    ) %>% 
  ggplot(aes(Color, Sales))  
  geom_col()  
  scale_x_reordered()  
  facet_wrap(~ fct_rev(Item), ncol = 1, scales = "free_y")  
  coord_flip()  
  theme_minimal()

Created on 2022-05-22 by the reprex package (v2.0.1)

  • Related