带多个变量的小提琴分组图

时间:2020-08-02 10:28:14

标签: r ggplot2 stack violin-plot

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

问题在于,堆叠似乎只给了我两列,这意味着我无法添加第三列进行分组(在这种情况下为性别),因此我无法遵循R gallery示例。

基本上,我希望能够生成与以下相同的图形,但是将每个小提琴图分为两个,一个用于男性,一个用于女性。因此,例如,不是在黄色的 comfort.trustmainstreammedia 图中,而是在另一个 comfort.trustmainstreammedia 图上方有一个 comfort.trustmainstreammedia 图,并带有与 male female 相对应的颜色,总共有六个小提琴图。

以下是一些示例数据:

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")

...将生成此图: enter image description here

1 个答案:

答案 0 :(得分:2)

可以使用stack代替数据pivot_longer。这将保留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