#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
Вы можете многое настроить, см. CRAN, GH и его полные документы.