Множественная категориальная полоса относительной частоты PLot - PullRequest
0 голосов
/ 31 мая 2019

Я хочу построить несколько графиков относительной пропорции частоты. Вот мои категории: пьяный, пьяный, жилье. Это выглядит примерно так:

housing: 1, 2, 3, 1, 4, 3, 1, 2
drunk: 1, 0, 1, 0, 0, 0, 0, 1
hsdrunk: 1, 0, 0, 1, 0, 0, 1, 1

Я хочу построить пропорциональную частоту выпитого по категориям жилья, но также разделить его значением hsdrunk (1 или 0).

Мне удалось создать что-то пропорциональное категории жилья, но я не уверен, как добавить дополнительную категорию «hsdrunk»。

png("Graphs/Analysis_Figure1.png")

analysis %>%  

 count(housing, drunk) %>% 

group_by(housing) %>% 

 mutate(freq = n/sum(n)) %>% 

 filter(drunk == 1) %>%

ggplot(aes(x = housing, y = freq, fill = drunk)) + 

geom_bar(stat="identity", position = 'dodge')

dev.off()

Вот мой желаемый вывод:

Desired Output

Это мой результат:

Actual Output

1 Ответ

0 голосов
/ 01 июня 2019

Я действительно не думаю, что вы хотите использовать position = "dodge" для этого.У вас будут проблемы с шириной полосы, расстоянием и даже маркировкой.Для этого в ggplot2 сделано facet_grid().Тогда большая часть магии заставить ее выглядеть так, как вы хотите, на самом деле происходит в theme().

. Я прошёл полное решение ниже.Я действительно хочу, чтобы вы имели представление о том, как ggplot2 был построен , чтобы справиться с этим (используя фасеты и элементы темы).В грамматике графики этот способ мышления подразумевает естественное течение.

Я построил его до степени , которую я сделал, чтобы дать вам некоторое вдохновение просто как это можно сделать с помощью theme().В противном случае, честно говоря, как еще вы можете быть уверены, что я указываю вам в правильном направлении?Элементы темы и остальные элементы ggplot2 становятся более интуитивно понятными при использовании.Вот еще много часов практики.


Вот данные, которые вы предоставили.Я добавил ключи к вашим факторным уровням в качестве именованных векторов (угадывая, что означает что, на основе позиционирования графика)Вы заметите, что я уже выпекал несколько разрывов строк (\n) до уровней корпуса, чтобы сделать построение графиков простым и приятным.

library(tidyverse)

analysis <- tribble(
  ~housing, ~drunk, ~hsdrunk,
         1,      1,        1,
         2,      0,        0,
         3,      1,        0,
         1,      0,        1,
         4,      0,        0,
         3,      0,        0,
         1,      0,        1,
         2,      1,        1
)
housing_levels <- c(
      `1` = "Not\nAlc.-Free",
      `2` = "Assigned"      ,
      `3` = "All\nAlc.-Free",
      `4` = "Requested"
)
hsdrunk_levels <- c(
      `0` = "Low HS Drinking",
      `1` = "High HS Drinking"
)

Это незначительная настройка, но ваши метки оси Yдовольно специфично: 0 выражается как «0», а десятичные дроби не имеют начальных 0.Вы можете сделать это с помощью пользовательской функции, подобной этой:

label_y <- function(y) {
  y <- scales::number(y, accuracy = .1)
  y[y == "0.0"] <- "0"
  sub("0.", ".", y, fixed = TRUE)
}

Я установил цвет вашего бара (почему бы и нет) и даже взглянул на цвет фона вашего графика.Есть нюансы, о которых я хотел бы знать, когда вы указываете цвет фона.(См. Раздел theme() ниже.)

darkslategrey <- "#1a476f"
whitesmoke <- "#eaf2f3"

Хорошо, давайте приступим к делу.

  • recode_factor() - это векторизованная switch() функция;он волшебным образом превращает эти цифры в реальные значения символов, которые вы хотите построитьВам, вероятно, не понадобится это с вашими базовыми данными, но это было полезно для меня. Обратите внимание: - это тот факт, что порядок ваших уровней факторов определяет порядок на странице.Используя recode_factor() вместо recode, я утверждаю порядок, который я установил в своих именованных векторах.
  • Затем я group_by() учусь в школе и пью.Поскольку drunk кодируется как 1 и 0, получить пропорцию очень просто;просто используйте mean(drunk) (не то, чтобы здесь были какие-то злые пьяницы).
  • При вызове facet_grid() я использую switch = "x", чтобы "переключить" положение метки сверху вниз.
  • Вы можете настроить расстояние между housing уровнями, используя аргумент width, равный geom_bar(), и расстояние между hsdrunk группами, используя вызов expand_scale() в scale_x_discrete().expand_scale() довольно крутая функция;Проверьте документы для expand_*_continuous() и expand_scale(), чтобы узнать больше.Вы также можете использовать элемент темы, panel.spacing, для разделения ваших групп.Но вы не можете этого сделать по причинам, которые я объясню ниже.
  • В операторе scale_y_continuous() вы увидите небольшие изменения, которые устанавливают разрывы и обозначают способ их отображения на «желаемом» графике.
  • Я также добавил заголовок, и здесь вы заметите, что я не уверен, что есть надежный способ выровнять его так, как он выровнен в вашем изображении.Как кладжа, он добавляет несколько пробелов, пока не будет выглядеть правильно.

Как я уже сказал, большая часть магии происходит в вызове theme().Есть множество способов сделать это, включая запуск с другой базовой темы и добавление оттуда.Все эти параметры подробно документированы в theme() документах , но это не будет большим ответом, если я просто скажу вам прочитать документы, не так ли?Я рекомендую вам запустить этот код без аргументов theme(), а затем добавить их один за другим и посмотреть, что они делают.Вот пошаговое руководство:

  • strip.placement и strip.background поместите метки hsdrunk вне оси x с прозрачным фоном.
  • График - это весь визуал, все, что входит в ваш png.График может иметь 1 или более панелей для визуализации данных;в вашем случае их два.plot.background и panel.background устанавливают цвета фона для каждого.
  • Но тогда у вас остались проблемы.( Примечание : Это нюанс, который я упомянул о цветах фона ...) Две белые панели разделены, и поскольку фон графика отличается от цвета, разделение действительно очевидно.Чтобы он выглядел как ваш «нужный» график, установите panel.spacing на 0, чтобы они образовали единую бесшовную белую область.Конечно, это также ставит ваши группы рядом друг с другом, но мы уже рассмотрели это, используя expand_scale().
  • У вас все еще нет линий сетки панели, потому что базовая сетка белая.Поэтому установите panel.grid.major.y на тот же цвет белого дыма, который вы использовали для фона графика.
  • axis.line возвращает вас к этой черной линии на осях X и Y.У вас может возникнуть соблазн использовать panel.border для этого, но panel.border поместит линии сверху, справа и даже между панелями.
  • Ваши метки оси Y повернуты вбок!Поэтому вам нужно изменить их angle на 90 °.hjust = .5 центрирует их по меткам.
  • Говоря о метках, у оси X на вашем последнем графике их нет.Поэтому вам нужно использовать axis.ticks.x, чтобы удалить их.Вы можете удалить заголовок оси X таким же образом.
  • Наконец, у вас есть подпись слева, что достигается с hjust (горизонтальное выравнивание) 0. 0. 1122 *
analysis %>% 
  mutate(
    housing = recode_factor(housing, !!!housing_levels),
    hsdrunk = recode_factor(hsdrunk, !!!hsdrunk_levels)
  ) %>% 
  group_by(hsdrunk, housing) %>% 
  summarise(drunk = mean(drunk, na.rm = TRUE)) %>% 
  ggplot(aes(x = housing, y = drunk)) +
  facet_grid(cols = vars(hsdrunk), switch = "x") +
  geom_bar(stat = "identity", fill = darkslategrey, width = .7) +
  scale_x_discrete(expand = expand_scale(add = 1)) +
  scale_y_continuous(
    name   = "Proportion drunk 3 or more times in past 30 days",
    breaks = function(limits) seq(limits[1], limits[2], by = .2),
    labels = label_y,
    expand = expand_scale(mult = c(0, .05))
  ) +
  labs(caption = paste0(
      "Figure 6: Students in All Housing Types\n",
      "                 Controlling for HS Drinking"
  )) +
  theme(
    strip.placement    = "outside",
    strip.background   = element_blank(),
    plot.background    = element_rect(fill = whitesmoke),
    panel.background   = element_rect(fill = "white"),
    panel.spacing      = unit(0, "lines"),
    panel.grid.major.y = element_line(color = whitesmoke),
    axis.line          = element_line(color = "black"),
    axis.text.y        = element_text(angle = 90, hjust = .5),
    axis.ticks.x       = element_blank(),
    axis.title.x       = element_blank(),
    plot.caption       = element_text(hjust = 0)
  )

enter image description here

Вам, возможно, не понадобится весь этот спор, в зависимости от того, насколько буквальным вы пытаетесь быть с этим желаемым сюжетом.В частности, вы можете упростить себе задачу, если отбросите цвет фона и если ваши факторы уже присутствуют в ваших данных и упорядочены должным образом.Но я хотел, чтобы у вас были все инструменты, необходимые для достижения поставленной цели с данными и параметрами, которые вы представили.Удачного кодирования!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...