#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())