0

I have some (admittedly chaotic) data and am trying to wrangle it into a figure using the code below. There are 2 things that I am struggling with.

  1. I want to change how test_level is displayed in the figure, so that 0 is "Test Under", 1 is "Test Medium", 2 is "Test Above Avg", and 3 is "Test Excellent". I tried creating a vector of these labels and coercing them using (labeller = as_labeller(facet_labels) within facet_grid() but it wouldn't take for some reason.

  2. I have been trying and failing to reorder 'var' so that the 'var' values display in the figure (from top to bottom) in this order:
    White
    Black
    Hispanic
    Other Race
    Male
    Female
    Less than HS
    Some HS
    Graduate HS
    Some College or Technical School
    Graduate College or Higher

I was originally trying to create a new variable that was essentially an 11-level factor variable with that order, but there must be a more succinct way to achieve this (if that would even work at all; I abandoned it in favor of asking here).

Code:

ggplot(df, aes(x = percent, y = var_factor, fill = group_factor_ordered)) +
  geom_col(orientation = "y", 
           color = "black") +
  facet_grid(group_factor_ordered ~ test_level,
             scales = "free", space = "free_y") +
  labs(title = "Demographic breakdown of Testing Level",
         y = "",
         x = "Percent") +
  theme_minimal() +
  theme(legend.position = "none",
        strip.text.y = element_blank())

Data:

df <- structure(list(group = c("gender", "gender", "gender", "gender", 
"gender", "gender", "gender", "gender", "p_educ", "p_educ", "p_educ", 
"p_educ", "p_educ", "p_educ", "p_educ", "p_educ", "p_educ", "p_educ", 
"p_educ", "p_educ", "p_educ", "p_educ", "p_educ", "p_educ", "p_educ", 
"p_educ", "p_educ", "race", "race", "race", "race", "race", "race", 
"race", "race", "race", "race", "race", "race", "race", "race", 
"race", "race"), levels = structure(c(1L, 1L, 1L, 1L, 2L, 2L, 
2L, 2L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 4L, 4L, 
4L, 4L, 5L, 5L, 5L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 
3L, 4L, 4L, 4L, 4L), .Label = c("1", "2", "3", "4", "5"), class = "factor"), 
    test_level = structure(c(1L, 2L, 3L, 4L, 1L, 2L, 3L, 4L, 1L, 
    2L, 3L, 4L, 1L, 2L, 3L, 4L, 1L, 2L, 3L, 4L, 1L, 2L, 3L, 4L, 
    2L, 3L, 4L, 1L, 2L, 3L, 4L, 1L, 2L, 3L, 4L, 1L, 2L, 3L, 4L, 
    1L, 2L, 3L, 4L), .Label = c("0", "1", "2", "3"), class = "factor"), 
    percent = c(1.7, 13.6, 17.6, 67, 1.6, 11.3, 14.9, 72.1, 4, 
    21.2, 13.5, 61.3, 2.7, 19.1, 19.9, 58.3, 0.8, 16.6, 18, 64.7, 
    1, 5.8, 17.3, 75.8, 1, 6.5, 92.5, 1, 5.8, 12.6, 80.6, 1.8, 
    13.3, 18.5, 66.4, 1.8, 14.6, 15.3, 68.3, 1, 7.7, 16.1, 75.2
    ), var = c("Female", "Female", "Female", "Female", "Male", 
    "Male", "Male", "Male", "Less than HS", "Less than HS", "Less than HS", 
    "Less than HS", "Some HS", "Some HS", "Some HS", "Some HS", 
    "Graduate HS", "Graduate HS", "Graduate HS", "Graduate HS", 
    "Some College or\nTechnical School", "Some College or\nTechnical School", 
    "Some College or\nTechnical School", "Some College or\nTechnical School", 
    "Graduate College\nor Higher", "Graduate College\nor Higher", 
    "Graduate College\nor Higher", "White", "White", "White", 
    "White", "Black", "Black", "Black", "Black", "Hispanic", 
    "Hispanic", "Hispanic", "Hispanic", "Other Race", "Other Race", 
    "Other Race", "Other Race"), group_factor = structure(c(1L, 
    1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
    2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 
    3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L), .Label = c("gender", 
    "p_educ", "race"), class = "factor"), group_factor_ordered = structure(c(2L, 
    2L, 2L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 
    3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 1L, 1L, 1L, 1L, 
    1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), .Label = c("race", 
    "gender", "p_educ"), class = "factor")), class = c("grouped_df", 
"tbl_df", "tbl", "data.frame"), row.names = c(NA, -43L), groups = structure(list(
    group = c("gender", "gender", "p_educ", "p_educ", "p_educ", 
    "p_educ", "p_educ", "race", "race", "race", "race"), levels = structure(c(1L, 
    2L, 1L, 2L, 3L, 4L, 5L, 1L, 2L, 3L, 4L), .Label = c("1", 
    "2", "3", "4", "5"), class = "factor"), .rows = structure(list(
        1:4, 5:8, 9:12, 13:16, 17:20, 21:24, 25:27, 28:31, 32:35, 
        36:39, 40:43), ptype = integer(0), class = c("vctrs_list_of", 
    "vctrs_vctr", "list"))), class = c("tbl_df", "tbl", "data.frame"
), row.names = c(NA, -11L), .drop = TRUE))
a_todd12
  • 449
  • 2
  • 12
  • 1
    *"I was originally trying to create a new variable that was essentially an 11-level factor variable with that order"* yes, that's the way. *"there must be a more succinct way to achieve this"* when you want a custom order based on real-word meaning, there's usually not a succinct way to code it. `df$var = factor(df$var, levels = c("White", "Black", "Hispanic", ...))` really isn't too bad. – Gregor Thomas Feb 08 '23 at 16:11

1 Answers1

2

For your facet labels you could use a named vector which serves as a lookup table and for your var the way to go is you 11-levels factor:

library(ggplot2)

test_labels <- c(
  "0" = "Test Under", "1" = "Test Medium",
  "2" = "Test Above Avg", "3" = "Test Excellent"
)

var_levels <- c(
  "Male", "Female", "Less than HS", "Some HS", "Graduate HS",
  "Some College or\nTechnical School", "Graduate College\nor Higher",
  "White", "Black", "Hispanic", "Other Race"
)

df$var_ordered <- factor(df$var, levels = rev(var_levels))

ggplot(df, aes(x = percent, y = var_ordered, fill = group_factor_ordered)) +
  geom_col(
    orientation = "y",
    color = "black"
  ) +
  facet_grid(group_factor_ordered ~ test_level,
    scales = "free", space = "free_y",
    labeller = labeller(test_level = test_labels)
  ) +
  labs(
    title = "Demographic breakdown of Testing Level",
    y = "",
    x = "Percent"
  ) +
  theme_minimal() +
  theme(
    legend.position = "none",
    strip.text.y = element_blank()
  )

enter image description here

stefan
  • 90,330
  • 6
  • 25
  • 51