R: создание расширенной линейчатой диаграммы с тремя категориальными переменными сводная таблица, прикрепленная внизу рисунка

#r #ggplot2 #geom-bar

#r #ggplot2 #геометрическая шкала

Вопрос:

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

У меня есть фрейм данных, который суммирует количество женщин и мужчин в двух местах (place1 и place2) для каждой возрастной группы. Меня интересуют пропорции мужчин и женщин в обоих местах и в каждой возрастной группе для сравнения. Данные выглядят следующим образом:

 # Females
data_female <- data.frame(agegroup = c("0-4","5-14","15-24","25-44","45-64","65-74","75-120"),
                          number_place1 = c(7000, 12000, 15000,40000, 36000, 10000, 13000),
                          number_place2 = c(163000, 360000, 350000,800000, 900000, 360000, 370000))
# Extra columns
data_female <- data_female %>%
               mutate(percentage_place1 = number / sum(number) * 100,
                      percentage_place2 = number / sum(number) * 100,
                      gender = "F") %>%
               select(agegroup, percentage_place1, percentage_place2, gender)

# Males
data_male <- data.frame(agegroup = c("0-4","5-14","15-24","25-44","45-64","65-74","75-120"),
                          number_place1 = c(6000, 13000, 13000,38000, 37000, 9000, 12000),
                          number_place2 = c(161000, 340000, 320000,699000, 900230, 330600, 385000))
# Extra columns
data_male <- data_male %>%
               mutate(percentage_place1 = number / sum(number) * 100,
                      percentage_place2 = number / sum(number) * 100,
                      gender = "M") %>%
               select(agegroup, percentage_place1, percentage_place2, gender)
  

Затем оба фрейма данных объединяются в один, и ‘pivot_longer’ используется для создания «длинного» фрейма данных:

 data <- rbind(data_females, data_males)

data_long <- data %>%
              rename(place1 = percentage_place1, place2 = percentage_place2) %>%
              pivot_longer(cols = c("place1","place2"),names_to = "place", values_to = "percentage")

  

В итоге у меня есть фрейм данных со следующими столбцами:

  • возрастная группа
  • пол (M / F)
  • место (место 1 / место 2)
  • процент (соотношение количества мужчин / женщин на место и на возрастную группу)

Из этого фрейма данных я хочу создать график, который выглядит точно так же, как рисунок, который можно найти здесь:

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

Это гистограмма с:

  • ось x: место и пол, вложенные в возрастную группу. Например, в пределах одной возрастной группы; у мужчин более светлый цвет (слева два столбца), а у женщин более темный цвет (справа два столбца); В каждом гендерном классе у нас есть два столбца: place1 = зеленый и place2 = синий.
  • ось y: процент (пропорция)

На данный момент у меня есть рисунок с таким кодом:

 ggplot(data_long, aes(x= agegroup, y=percentage, fill=interaction(place,sex)))     
  geom_bar(position='dodge', stat='identity')  
  facet_wrap( ~ name)

  

На этом рисунке есть два больших столбца, «place1» и «place2» (из-за face_wrap()), но я хочу объединить их в один столбчатый график в качестве примера рисунка. Кроме того, как я могу создать эту красивую таблицу под гистограммой, как в примере?

Надеюсь, вам понятно, что я имею в виду. Есть ли кто-нибудь, у кого есть опыт создания таких фигур?

Ответ №1:

Вы можете использовать подход «скрытых граней».

Сначала убедитесь, что ваши категориальные переменные расположены в нужном порядке:

 agelevels <- c("0-4", "5-14", "15-24", "25-44", "45-64", "65-74", "75-120")
data_long <- data_long %>% mutate(agegroup = factor(agegroup, agelevels),
                                  gender = factor(gender, c("M", "F")))
  

Затем мы строим график с указанием пола по оси x и заполняем в соответствии с взаимодействием между полом и местом. Затем мы разделяем по возрастным группам вдоль оси x, удаляя расстояние между панелями и границей каждой панели. Наконец, мы переключаем положение полосы фасета на нижнюю (снаружи) и удаляем ее фон, чтобы она выглядела как вторичная ось x:

 ggplot(data_long, aes(x = gender, y = percentage, 
                      fill = interaction(place, gender)))     
  geom_col(position = 'dodge', color = "gray50")  
  facet_grid( ~ agegroup, switch = "x")  
  scale_fill_manual(values = c("#a8d094", "#9fc0e7", "#97a891", "#95a5c2"),
                    labels = c("Male, place 1", "Male, place 2",
                               "Female, place 1", "Female, place 2"))  
  labs(fill = "", x = "Age group")  
  theme_bw()  
  theme(panel.spacing = unit(0, "points"),
        panel.border = element_blank(),
        axis.line = element_line(),
        strip.placement = "outside",
        strip.background = element_blank(),
        legend.position = "bottom",
        panel.grid.major.x = element_blank())
  

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