Две категориальные переменные на одной оси (не связанные)

#r #ggplot2

#r #ggplot2

Вопрос:

Я новичок в R, и по этому вопросу может быть очевидное решение, но я не нашел решения в Google.

Возможно ли в ggplot или другом пакете построения диаграмм создать диаграмму с двумя категориальными переменными (не иерархическими) на одной оси, например, gender и agegroup, как на прилагаемом чертеже.

Пример желаемой диаграммы

Ответ №1:

Во-первых, мы могли бы состряпать некоторые поддельные данные.

 ## making some fake data
dat <- tibble(
  variable=factor(c(rep("Gender", 4), rep("Age Group", 8)), levels=c("Gender", "Age Group")), 
  levels = factor(rep(c("Male", "Female", "18-29", "30-49", "50-67", "68-80"), each=2), 
                  levels=c("Female", "Male", "68-80", "50-67", "30-49", "18-29")), 
  attr = rep(c("a1", "a2"), 6), 
  values = runif(12, 20, 70)
)
dat <- dat %>% 
  group_by(levels) %>% 
  mutate(pct = values/sum(values))
dat
> dat
# # A tibble: 12 x 5
# # Groups:   levels [6]
#   variable  levels attr  values   pct
#   <fct>     <fct>  <chr>  <dbl> <dbl>
# 1 Gender    Male   a1      41.4 0.487
# 2 Gender    Male   a2      43.7 0.513
# 3 Gender    Female a1      35.8 0.534
# 4 Gender    Female a2      31.2 0.466
# 5 Age Group 18-29  a1      35.9 0.513
# 6 Age Group 18-29  a2      34.1 0.487
# 7 Age Group 30-49  a1      38.8 0.489
# 8 Age Group 30-49  a2      40.6 0.511
# 9 Age Group 50-67  a1      29.4 0.426
# 10 Age Group 50-67  a2      39.6 0.574
# 11 Age Group 68-80  a1      31.2 0.423
# 12 Age Group 68-80  a2      42.5 0.577
  

Тогда мы могли бы построить график с ggplot() . Использование facet_grid() будет делать то, что вы хотите, с точки зрения размещения разных групп по оси y.

 g <- ggplot(dat, aes(x=levels, y=pct, fill=attr))   
  geom_bar(position="stack", stat="identity")   
  coord_flip()   
  facet_grid(variable ~ ., scales="free")
  

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

Одна вещь, которую вы, возможно, захотите изменить, — это высота каждой панели. Вы можете сделать это, манипулируя внутренними элементами графика. Во-первых, вы должны получить grob.

 gg <- ggplotGrob(g)
  

Затем вы можете определить, какой высоты вы хотите, чтобы каждая панель была. Здесь мы скажем, что гендерная панель должна быть 2, а возраст должен быть 4. Они не указаны в каких-либо конкретных единицах измерения, они представляют только относительную высоту каждой.

 h <- c(2,4)
  

Далее нам нужно найти место в heights элементе gg объекта для замены. Мы хотим заменить "1null" элементы на высоты, которые мы определили. Ниже height.inds будут номера наблюдений gg$heights элемента, который нам нужно заменить.

 height.inds <- grep("1null", gg$heights)
  

Далее мы можем заменить соответствующие элементы нашими новыми высотами

 gg$heights[height.inds] <- unit(h, "null")
  

И заново нарисуйте график:

 grid.draw(gg)
  

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

Ответ №2:

Возможно, было бы проще попытаться объединить два графика вместо огранки.

Данные

 dat <- expand.grid(gender = c("A","B"), age = c("18-29","30-49","50-67","68-80"), reply = c("Y", "N"))
set.seed(42)
dat$value = sample(30, size= nrow(dat), replace = TRUE)
head(dat)
#   gender   age reply value
# 1      A 18-29     Y    17
# 2      B 18-29     Y    15
# 3      A 30-49     Y    24
# 4      B 30-49     Y     7
# 5      A 50-67     Y     4
# 6      B 50-67     Y    25
  

Код

 library(ggplot2)
library(patchwork)
gg1 <- ggplot(dat, aes(x = gender, y = value, fill = reply))  
  geom_bar(position = "stack", stat = "identity")  
  coord_flip()
gg2 <- ggplot(dat, aes(x = age, y = value, fill = reply))  
  geom_bar(position = "stack", stat = "identity")  
  coord_flip()
gg1 / gg2
  

столбчатые графики ggplot2, сложенные

Вы можете многое настроить, см. CRAN, GH и его полные документы.