具有多个变量的分组小提琴图表

Grouped violin chart with multiple variables

我正在尝试使用 ggplot2 制作分组小提琴图表,类似于 R 画廊中的 this one。在没有分组的情况下,我能够通过堆叠数据来制作一个小提琴图,将单独的列作为我的类别。我已经复制了示例数据和工作代码以及下面的图形输出。

问题是堆叠似乎只给了我两列,这意味着我无法添加第三列用于分组(在本例中为性别),所以我无法按照 R gallery 示例进行操作。

基本上,我希望能够生成与下面相同的图表,但将每个小提琴情节分成两份,一份用于男性,一份用于女性。因此,例如,黄色的 comfort.trustmainstreammedia 图将有一个 comfort.trustmainstreammedia 图在另一个 comfort.trustmainstreammedia剧情,颜色分别对应,会有6个小提琴地块总数。

下面是一些示例数据:

structure(list(comfort.trustmainstreammedia = c(100, 96, 100, 
40, 80, 100, 100, 100, 100, 100), comfort.democracybest = c(100, 
94, 100, 92, 80, 100, 45, 70, 100, 100), comfort.capitalismbest = c(100, 
90, 100, 86, 80, 100, 30, 100, 100, 100), gender = c("Male", 
"Female", "Male", "Female", "Male", "Female", "Male", "Male", 
"Male", "Male")), row.names = c(NA, -10L), class = c("tbl_df", 
"tbl", "data.frame"), .Names = c("comfort.trustmainstreammedia", 
"comfort.democracybest", "comfort.capitalismbest", "gender"))

这是我生成图表的代码:

p <- stack(select(mwe, starts_with("comfort.")))
names(p)[names(p) == "values"] <- "value"
names(p)[names(p) == "ind"] <- "text"
p$text = with(p, reorder(text, value, mean))
p <- p %>%
  ggplot( aes(x=text, y=value, fill=text, color=text)) +
  geom_violin(width=1.4, size=0.2, trim=TRUE) +
  scale_fill_viridis(discrete=TRUE) +
  scale_color_viridis(discrete=TRUE) +
  theme(
    legend.position="none"
  ) +
  coord_flip() + # This switch X and Y axis and allows to get the horizontal version
  xlab("Question") +
  ylab("%") +
  title("Comfort")
p + stat_summary(fun=mean, geom="point", shape = 23, size=1, color="black")

...生成此图:

您可以使用 pivot_longer 代替 stack 来准备数据。这将保留 gender 列,然后可以将其映射到 colorfill。试试这个:

library(ggplot2)
library(dplyr)
library(tidyr)
library(viridis)

d <- mwe %>% 
  tidyr::pivot_longer(-gender, names_to = "text") %>% 
  mutate(text = reorder(text, value, mean))

p <- ggplot(d, aes(x=text, y=value, fill=gender, color=gender)) +
  geom_violin(width=1.4, size=0.2, trim=TRUE) +
  scale_fill_viridis(discrete=TRUE) +
  scale_color_viridis(discrete=TRUE) +
  theme(legend.position="none") +
  coord_flip() + # This switch X and Y axis and allows to get the horizontal version
  xlab("Question") +
  ylab("%") +
  ggtitle("Comfort")

p + stat_summary(fun=mean, geom="point", shape = 23, size=1, color="black")
#> Warning: position_dodge requires non-overlapping x intervals