Two columns layout Quarto

library(tidyverse)
── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
✔ dplyr     1.1.4     ✔ readr     2.1.5
✔ forcats   1.0.0     ✔ stringr   1.5.1
✔ ggplot2   3.5.1     ✔ tibble    3.2.1
✔ lubridate 1.9.3     ✔ tidyr     1.3.1
✔ purrr     1.0.2     
── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag()    masks stats::lag()
ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
theme_set(theme_grey(base_size = 25))

library(tidyverse)


qname_levels_single_response_crosswalk <- readr::read_csv('https://raw.githubusercontent.com/rfordatascience/tidytuesday/master/data/2024/2024-09-03/qname_levels_single_response_crosswalk.csv')
Rows: 122 Columns: 3
── Column specification ────────────────────────────────────────────────────────
Delimiter: ","
chr (2): qname, label
dbl (1): level

ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
stackoverflow_survey_questions <- readr::read_csv('https://raw.githubusercontent.com/rfordatascience/tidytuesday/master/data/2024/2024-09-03/stackoverflow_survey_questions.csv')
Rows: 24 Columns: 2
── Column specification ────────────────────────────────────────────────────────
Delimiter: ","
chr (2): qname, question

ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
stackoverflow_survey_single_response <- readr::read_csv('https://raw.githubusercontent.com/rfordatascience/tidytuesday/master/data/2024/2024-09-03/stackoverflow_survey_single_response.csv')
Rows: 65437 Columns: 28
── Column specification ────────────────────────────────────────────────────────
Delimiter: ","
chr  (2): country, currency
dbl (26): response_id, main_branch, age, remote_work, ed_level, years_code, ...

ℹ Use `spec()` to retrieve the full column specification for this data.
ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
qfilter <- function(q) {
  qname_levels_single_response_crosswalk %>% 
    filter(qname == q) %>% 
    select(level, label) %>% 
    rename_with(~q, level) %>% 
    rename_with(~paste0(q, "_label"), label)
}

age_levels <- c("Under 18 years old",
                "18-24 years old",
                "25-34 years old",
                "35-44 years old",
                "45-54 years old",
                "55-64 years old",
                "65 years or older",
                "Prefer not to say"
                ) %>% 
  str_remove(., " years( old)*")

ai_sent_levels <- c("Very unfavorable",
                    "Unfavorable",
                    "Indifferent/Unsure",
                    "Favorable",
                    "Very favorable")


stack_overflow_ai <- stackoverflow_survey_single_response %>% 
  left_join(qfilter("age")) %>% 
  left_join(qfilter("main_branch")) %>% 
  left_join(qfilter("ai_sent")) %>% 
  mutate(age_label = str_remove(age_label, " years( old)*")) %>% 
  # filter(ai_sent_label != "Unsure") %>%
  mutate(ai_sent_label = case_when(
    ai_sent_label == "Indifferent" | ai_sent_label == "Unsure" ~ "Indifferent/Unsure",
    TRUE ~ ai_sent_label
  )) %>% 
  mutate(
    age_label = fct_relevel(age_label, age_levels),
    ai_sent_label = fct_relevel(ai_sent_label, ai_sent_levels)
  )
Joining with `by = join_by(age)`
Joining with `by = join_by(main_branch)`
Joining with `by = join_by(ai_sent)`

P1

A fill-position bar ggplot

library(ggplot2)


stack_overflow_ai |>
  ggplot() + 
  aes(y = age_label) + 
  aes(fill = ai_sent_label) + 
  geom_bar(position = "fill") + 
  NULL +
  NULL +
  theme(legend.position = "none") + 
  labs(y = NULL, fill = NULL, x = NULL)

P2

A likert plot with ggstats

library(ggplot2)
library(ggstats)

stack_overflow_ai |>
  ggplot() + 
  aes(y = age_label) +
  aes(fill = ai_sent_label) + 
  geom_likert() + 
  geom_likert_text(hide_below = 0.03) +
  scale_fill_likert() +
  theme(legend.position = "none") + 
  labs(y = NULL, fill = NULL, x = NULL)

  1. Overwrite y mapping

Second column

and here

More text

:::