reordering plot based on another dataframe

I feel like this should be trivial but I can't figure it out.

I want to reorder the x-axis of one graph based on the output of another dataframe where I've calculated some other variable and arranged it in descending order. So specifically in the below example, I want to reorder the x-axis by order_df: it should read 2, 3, 1 (which is the descending order of other_var: 200, 60, 40).

library(tidyverse)

graph_df <- data.frame(
  trial = factor(c(1,1,2,2,3,3)),
  probability = c(90,10,50,50,10,90),
  group = factor(c(1,2,1,2,1,2))
)

ggplot(graph_df, aes(x = trial, y = probability, fill = group)) +
  geom_col() +
  theme_minimal() +
  theme(
    legend.position = "bottom"
  )


order_df <- data.frame(
  trial = c(1, 2, 3),
  other_var = c(40, 200, 60)
) %>%
  arrange(desc(other_var)) %>%
  pull(trial) 

ggplot(graph_df, aes(x = fct_reorder(trial, order_df), y = probability, fill = group)) +
  geom_col() +
  theme_minimal() +
  theme(
    legend.position = "bottom"
  )
#> Error in fct_reorder(trial, order_df): length(f) == length(.x) is not TRUE

Created on 2019-03-18 by the reprex package (v0.2.1)

Ok, I think I've got a solution by using left_join but I'm open to any other solutions too. I'm not sure how robust this is atm...:

library(tidyverse)

graph_df <- data.frame(
  trial = factor(c(1,1,2,2,3,3)),
  probability = c(90,10,50,50,10,90),
  group = factor(c(1,2,1,2,1,2))
)

order_df <- data.frame(
  trial = factor(c(1, 2, 3)),
  other_var = c(40, 200, 60)
) %>%
  arrange(desc(other_var)) %>%
  mutate(id = row_number())

graph_df %>%
  left_join(order_df, by = "trial") %>%
ggplot(aes(x = fct_reorder(trial, id), y = probability, fill = group)) +
  geom_col() +
  theme_minimal() +
  theme(
    legend.position = "bottom"
  )

Created on 2019-03-18 by the reprex package (v0.2.1)

Hi mrblobby,

I think your first try was pointing in the right direction :wink: I would use factor(x, levels) to recode the levels of interest based on your another data frame. Below you will find the possible solution...

Best regards
Adam

library(tidyverse)

graph_df <- data.frame(
  trial = factor(c(1,1,2,2,3,3)),
  probability = c(90,10,50,50,10,90),
  group = factor(c(1,2,1,2,1,2))
)

order_df <- data.frame(trial = c(1, 2, 3),
                       other_var = c(40, 200, 60)) %>%
  arrange(desc(other_var)) %>%
  pull(trial) 

ggplot(graph_df, aes(x = trial, y = probability, fill = group)) +
  geom_col() +
  theme_minimal() +
  theme(legend.position = "bottom")


ggplot(graph_df, aes(x = factor(trial, levels=order_df), 
                     y = probability, fill = group)) +
  geom_col() +
  theme_minimal() +
  theme(legend.position = "bottom")

Created on 2019-03-19 by the reprex package (v0.2.1)

2 Likes

Otherwise, try...

fct_relevel(graph_df$trial, as.character(order_df))
1 Like

Much better, thanks!

1 Like

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.