Свяжите два ggplot в R: одну шкалу Лайкерта и одну столбчатую диаграмму в одном графике.

Вопрос или проблема

У меня есть дата-фрейм под названием df в R :

# Загружаем необходимые библиотеки
library(tibble)
library(tidyverse)
library(ggplot2)
library(ggpubr)
library(ggstats)

# Определяем категории и уровни Ликерта
var_levels <- c("A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q")

likert_levels <- c(
  "Абсолютно не согласен",
  "Не согласен",
  "Ни согласен, ни не согласен",
  "Согласен",
  "Абсолютно согласен"
)

# Устанавливаем сид для воспроизводимости
set.seed(42)

# Создаем дата-фрейм с тремя колонками ответов по Ликерту
df <- tibble(
  var = sample(var_levels, 50, replace = TRUE),  # Случайные значения от A до Q
  val1 = sample(likert_levels, 50, replace = TRUE) # Случайные значения от уровней Ликерта
  
)

# Просматриваем первые несколько строк дата-фрейма
print(df)

Я использую решение, которое было ранее предложено здесь, чтобы расширить его и попросить добавить другой столбик рядом с ним, который будет содержать количество каждой категории. Каждая колонка должна соответствовать горизонтальной шкале Ликерта слева. Как я могу это сделать в R?

ibrary(tidyverse)
library(ggstats)

dat <- df |>
  mutate(
    across(-var, ~ factor(.x, likert_levels))
  ) |>
  pivot_longer(-var, names_to = "group") |>
  count(var, value, group) |>
  complete(var, value, group, fill = list(n = 0)) |>
  mutate(
    prop = n / sum(n),
    prop_lower = sum(prop[value %in% c("Абсолютно не согласен", "Не согласен")]),
    prop_higher = sum(prop[value %in% c("Абсолютно согласен", "Согласен")]),
    .by = c(var, group)
  ) |>
  arrange(group, prop_lower) |>
  mutate(
    y_sort = paste(var, group, sep = "."),
    y_sort = fct_inorder(y_sort)
  )

top10 <- dat |>
  distinct(group, var, prop_lower) |>
  slice_max(prop_lower, n = 10, by = group)

dat <- dat |>
  semi_join(top10)

dat_tot <- dat |>
  distinct(group, var, y_sort, prop_lower, prop_higher) |>
  pivot_longer(-c(group, var, y_sort),
    names_to = c(".value", "name"),
    names_sep = "_"
  ) |>
  mutate(
    hjust_tot = ifelse(name == "lower", 1, 0),
    x_tot = ifelse(name == "lower", -1, 1)
  )

ggplot(dat, aes(y = y_sort, x = prop, fill = value)) +
  geom_col(position = position_likert(reverse = FALSE)) +
  geom_text(
    aes(
      label = label_percent_abs(hide_below = .05, accuracy = 1)(prop),
      color = after_scale(hex_bw(.data$fill))
    ),
    position = position_likert(vjust = 0.5, reverse = FALSE),
    size = 3.5
  ) +
  geom_label(
    aes(
      x = x_tot,
      label = label_percent_abs(accuracy = 1)(prop),
      hjust = hjust_tot,
      fill = NULL
    ),
    data = dat_tot,
    size = 3.5,
    color = "black",
    fontface = "bold",
    label.size = 0,
    show.legend = FALSE
  ) +
  scale_y_discrete(labels = \(x) gsub("\\..*$", "", x)) +
  scale_x_continuous(
    labels = label_percent_abs(),
    expand = c(0, .15)
  ) +
  scale_fill_brewer(palette = "BrBG") +
  facet_wrap(~group,
    scales = "free_y", ncol = 1,
    strip.position = "right"
  ) +
  theme_light() +
  theme(
    legend.position = "bottom",
    panel.grid.major.y = element_blank()
  ) +
  labs(x = NULL, y = NULL, fill = NULL)

введите описание изображения здесь

Моя попытка


dat%>%
  select(var,n)%>%
  group_by(var)%>%
  summarise(count = sum(n))%>%
  ggplot(., aes(y = var, x = count)) +
  geom_bar(stat = "identity", fill = "lightgrey")+labs(x="Количество ответов",y="")+
  geom_text(aes(label = count),position = position_stack(vjust = .5)) +
  theme_bw()+
  theme(
    axis.text.y = element_blank(),
    axis.ticks.y = element_blank(),
    axis.text.x = element_blank(),   # Удалить текст по оси x
    axis.ticks.x = element_blank()    # Удалить деления по оси x
  )


введите описание изображения здесь
Но как мне их объединить рядом друг с другом, чтобы они также соответствовали двум колонкам?

Ответ или решение

Чтобы объединить графики Likert и столбчатую диаграмму в одном изображении с помощью R, вы можете использовать пакет ggpubr, который позволяет удобно комбинировать ggplot-объекты. Ниже я представлю пошаговую инструкцию, исходя из данных, с которыми вы работаете, а также готовый код для реализации вашей задачи.

1. Подготовка данных

Вы уже создали датафрейм df с ответами Likert и категориями. Теперь мы должны создать необходимые графики.

2. Создание графика Likert

Это уже было реализовано в вашем коде. Убедитесь, что вы правильно подготовили данные и создаете сам график, как в вашем примере. Мы сосредотачиваемся на графиках, которые будут комбинироваться.

3. Создание столбчатой диаграммы

Вы уже сделали начальную попытку в своем коде. Вам нужно будет немного доработать код, чтобы он поставлял правильные значения для столбчатой диаграммы.

4. Объединение графиков

Для объединения графиков Ликерта и столбчатых диаграмм используйте функцию ggarrange из пакета ggpubr.

Вот итоговый комбинированный код:

# Загрузка необходимых библиотек
library(tibble)
library(tidyverse)
library(ggplot2)
library(ggpubr)

# Определение категорий и уровней Ликерта
var_levels <- c("A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q")

likert_levels <- c(
  "Strongly disagree",
  "Disagree",
  "Neither agree nor disagree",
  "Agree",
  "Strongly agree"
)

# Установка начального значения для воспроизводимости
set.seed(42)

# Создание датафрейма с тремя столбцами ответов Ликерта
df <- tibble(
  var = sample(var_levels, 50, replace = TRUE),  
  val1 = sample(likert_levels, 50, replace = TRUE)
)

# Подготовка данных для диаграммы Ликерта
dat <- df |>
  mutate(across(-var, ~ factor(.x, likert_levels))) |>
  pivot_longer(-var, names_to = "group") |>
  count(var, value, group) |>
  complete(var, value, group, fill = list(n = 0)) |>
  mutate(prop = n / sum(n)) |>
  arrange(group, prop)

# Построение графика Ликерта
likert_plot <- ggplot(dat, aes(y = var, x = prop, fill = value)) +
  geom_col(position = position_fill(reverse = FALSE)) +
  theme_light() +
  labs(x = "Proportion", y = "Categories", fill = "Response") +
  scale_fill_brewer(palette = "BrBG")

# Подготовка данных для столбчатой диаграммы
bar_data <- df %>%
  group_by(var) %>%
  summarise(count = n())

# Построение столбчатой диаграммы
bar_plot <- ggplot(bar_data, aes(y = var, x = count)) +
  geom_bar(stat = "identity", fill = "lightgrey") +
  geom_text(aes(label = count), position = position_stack(vjust = .5)) +
  theme_bw() +
  labs(x = "Response Count", y = "") +
  theme(axis.text.y = element_blank(),
        axis.ticks.y = element_blank(),
        axis.text.x = element_blank(),
        axis.ticks.x = element_blank())

# Объединение графиков
combined_plot <- ggarrange(likert_plot, bar_plot, ncol = 2, nrow = 1)
combined_plot

5. Настройка и вывод результата

Обратите внимание, что при настройке столбчатой диаграммы и диаграммы Ликерта стоит убедиться, что оси правильно согласованы, чтобы визуальные элементы были сопоставимы.

Заключение

Используйте предложенный код в вашем R-скрипте, чтобы получить желаемое визуальное представление. Объединив графики, вы не только повысите информативность, но и улучшите восприятие данных, что очень важно в аналитике.

Оцените материал
Добавить комментарий

Капча загружается...