0
votes

I am trying to plot a graph with ggplot where I facet on one variable, and make two plots (one for each variable showing a value (x) for a category (y), where y is plotted in descending order with respect to X within each group. The issue here is that in each group, the same y label exists and this seems to mess up the factor levels.

Setting up the data:

dummy_data <- tibble(
  
  y_var = c('v1', 'v2', 'v3', 'v4', 'v5', 'v2', 'v6', 'v7', 'v4', 'v7'),
  x_var = c(0.0629, 0.0631, 0.0654, 0.0657, 0.0676, 0.0693, 0.0707, 0.0728, 0.0733, 0.0868),
  group_var = c("A", "B", "B", "A", "B", "A", "A", "A", "B", "B")
  
) %>% 
  group_by(group_var) %>% # group by the grouping variable
  arrange(x_var, .by_group = TRUE) %>% # arrange the rows by x_var, within each group
  mutate(y_var = factor(y_var, levels = y_var)) # change the y variable to a factor to retain order when plotting

dummy_data %>%
  ggplot() +
  geom_point(aes(x = x_var, y = y_var, color = group_var), size = 5) +
  facet_wrap(~group_var, scales = 'free', dir = 'v')

The output, shown below, is not ordered as desired.

enter image description here

This can be rectified by making all y_var values unique (adding group name to the value), however this is not desirable because this changes y axis labels (shown below)

dummy_data %>%
  mutate(y_var = str_c(y_var, group_var),
         y_var = factor(y_var, levels = y_var)) %>%
  ggplot() +
  geom_point(aes(x = x_var, y = y_var, color = group_var), size = 5) +
  facet_wrap(~group_var, scales = 'free', dir = 'v')

enter image description here

I would like to produce the second graph, without having to change the value of all y_var. Thanks!

1
What happens if there is a factor value for group B that does not exist in group A? For example V3 and V5 do not exist for group A, what dictates where they should be displayed for group B?Andrew Chisholm

1 Answers

1
votes

tidytext::reorder_within() does something similar, and in combination with tidytext::scale_y_reordered() helps with tidying the output to look like your goal.

library(tidytext)

dummy_data %>%
  mutate(y_var = reorder_within(y_var,  x_var, group_var)) %>%
  ggplot() +
  geom_point(aes(x = x_var, y = y_var, color = group_var), size = 5) +
  scale_y_reordered() +
  facet_wrap(~group_var, scales = 'free', dir = 'v')

enter image description here