【问题标题】:Stacked bar plot with 4 categorical variables in RR中具有4个分类变量的堆积条形图
【发布时间】:2016-08-10 15:22:48
【问题描述】:

我的问题是能够在 R 的条形图中显示 4 个分类变量。

这 4 个分类变量各有 2 个或更多级别。我的想法是使用ggplot 使用geom_bar 为3 个类别中的每一个创建单独的条形图,每个级别的计数将被堆叠。然后我会使用facet_wrap 然后将其按第 4 类分开。

数据如下:

Species     Crown_Class     Life_class      Stem_Category
E. obliqua  Suppressed      Standing live   Large stems
E. rubida   Intermediate    Standing live   Large stems
E. obliqua  Suppressed      Standing live   Small stems
E. obliqua  Suppressed      Standing live   Small stems
E. rubida   Suppressed      Standing live   Large stems
E. radiata  Suppressed      Standing live   Small stems
E. obliqua  Dominant        Standing live   Small stems
E. obliqua  Suppressed      Standing live   Small stems
E. radiata  Suppressed      Standing live   Large stems
E. rubida   NA              Standing dead   Large stems
E. rubida   Intermediate    Standing live   Large stems

我想到的图表显示了三个类别中的每一个的堆叠条,然后按三分之一分组。对于给定的数据,将为每个物种显示 Crown_Class、life_class 和 Stem_Category 的单独条形。

我已经尝试了几个小时,并且可以使用此代码进行单独的绘图(我将数据分成 3 个单独的数据框来执行此操作:

ggplot(data= cc, aes(x= Species, fill = Crown_Class))+
geom_bar(position='stack')

ggplot(data=lc, aes(x = Species, fill = Life_class))+
geom_bar(position ='stack')

ggplot(data=sc, aes(x = Species, fill = Stem_Category))+
geom_bar(position ='stack')

这个想法是做这样的事情:

ggplot()+
  geom_bar(data= cc, aes(x = Species, fill = Crown_Class), 
      position='stack') +
  geom_bar(data=lc, aes(x = Species, fill = Life_class), 
      position ='dodge')+
  facet_wrap(~Species)

但结果不是我想的那样。第二个情节有效地覆盖了第一个情节。

如果有任何帮助,我将不胜感激。

【问题讨论】:

  • 就这样,你如何处理 NA?
  • 你可以试试facet_grid
  • 抱歉 - 我的图片有点错误。刚刚改了。 @ArtificialBreeze,第二个情节覆盖了第一个情节 - 你可以看到后面的颜色。回复:NA"s 这是另一个问题 - 使用 na.rm = TRUE 可能是这样。
  • 谢谢@bouncyball,但`facet_grid'会给我另一个块。目的是在 3 个方面获得 3 个条形。
  • 好的,我以为你不处理它们,这有时会导致情节出现问题

标签: r plot ggplot2 bar-chart


【解决方案1】:

这是一个示例,说明如何使用 facet_grid 将所有 4 个变量包含在同一个图上。

请注意,我生成了一些虚拟数据,因为我无法将您的数据集导入R

生成数据

library(ggplot2)
theme_set(theme_bw())
set.seed(123)
df1 <- data.frame(s1 = sample(letters[1:3], 11, replace = T),
                  s2 = sample(letters[4:6], 11, replace = T),
                  s3 = sample(letters[7:9], 11, replace = T),
                  s4 = sample(letters[10:12], 11, replace = T),
                  stringsAsFactors = FALSE)

编辑:

也许这更接近你所追求的:

ggplot(df1)+
    geom_bar(aes(x = s1), position = 'stack')+
    geom_bar(aes(x = s2), position = 'stack')+
    geom_bar(aes(x = s3), position = 'stack')+
    facet_wrap(~ s4)

如果你以这种方式进行,你一定要注意x轴上的值来自三个不同的变量

恕我直言:虽然我不是这方面的专家,但我确实认为在同一轴上创建具有三个不同变量的可视化有点可疑,ggplot2 为您提供了很多选项来避免继续以这种方式。

使用facet_grid进行绘图

ggplot(df1, aes(x = s1, fill = s2))+
    geom_bar(position = 'stack')+
    facet_grid(s3~s4)

使用interactionfacet_wrap 进行绘图

现在,假设您不希望将这两个分组因素作为方面,而只喜欢一个方面。然后,我们就可以使用interaction函数了。

ggplot(df1, aes(x = s1, fill = interaction(s2,s3)))+
    geom_bar(position = 'stack')+
    facet_wrap(~s4)

使用Rmisc::multiplot

最后,我们可以创建三个独立的绘图,然后使用Rmisc::multiplot在同一页面上绘图。

library(Rmisc)
p1 <- ggplot(df1, aes(x = s1, fill = s2))+
    geom_bar(position = 'stack')
p2 <- ggplot(df1, aes(x = s1, fill = s3))+
    geom_bar(position = 'stack')
p3 <- ggplot(df1, aes(x = s1, fill = s4))+
    geom_bar(position = 'stack')

multiplot(p1,p2,p3, cols = 3)

【讨论】:

  • 不错的答案,但它并没有完全给出我想要的结果 - 目的是获得前三个类别之间没有交互的东西。它们只需要显示为堆叠条形,显示第 4 个类别的类别中每个级别的计数。几乎就像前三个类别都在 x 轴上,它们的计数在 y 轴上一样。然后按第四类划分。
  • @AlisonBennett 所以三个不同的变量会被分组在同一个轴上?
  • 是的,有可能吗?
  • 再次感谢,它快到了,但现在无法正确堆叠。 IE。在您的示例中,a、b 和 c 应该堆叠。注意。我听到了你的评论——但是因为每个分类变量的总数是相同的——我认为做这个图是合理的。
【解决方案2】:

由于您尝试使用 Crown_ClassLife_classStem_Category 来区分您的图,ggplot2 更希望这些值位于它们自己的列中(通常 ggplot2 像长数据,其中只有一列包含正在绘制的值。)我们可以使用 tidyr 重新组织数据。

library(tidyr)
df <-
  gather(df, variable, value, -Species)

head(df)
     Species    variable           value
1 E. obliqua Crown_Class      Suppressed
2  E. rubida Crown_Class    Intermediate
3 E. obliqua Crown_Class      Suppressed
4 E. obliqua Crown_Class      Suppressed
5  E. rubida Crown_Class      Suppressed
6 E. radiata Crown_Class      Suppressed

现在我们可以在variable上进行分面换行

ggplot(df) +
  geom_bar(aes(x = Species, fill = value)) +
  facet_wrap(~ variable) 

如果您不喜欢只为Crown_ClassLife_class 和“Stem_Category”的所有颜色提供一个指南,您可以制作三个单独的图并使用gridExtra 包将它们组合起来。

library(dplyr)
library(gridExtra)
p <-
  df %>%
  filter(variable == 'Crown_Class') %>%
  ggplot() +
  geom_bar(aes(x = Species, fill = value)) +
  facet_wrap(~ variable)

q <-
  df %>%
  filter(variable == 'Life_class') %>%
  ggplot() +
  geom_bar(aes(x = Species, fill = value)) +
  facet_wrap(~ variable)

r <-
  df %>%
  filter(variable == 'Stem_Category') %>%
  ggplot() +
  geom_bar(aes(x = Species, fill = value)) +
  facet_wrap(~ variable)

grid.arrange(p, q, r)

【讨论】:

  • 谢谢。我喜欢这个答案,不是我的目标,但确实提供了一个很好的解决方案。我在使用 gridExtra 选项时遇到了一点问题。当我运行 grid.arrange 部分时,出现此错误“layout_base 中的错误(数据,vars,drop = drop):至少一层必须包含用于构面的所有变量” - 你知道它是什么吗?
  • @AlisonBennett 该错误意味着facet_wrap 调用在绘图 p、q 和 r 某处发生了一些事情。您是否对数据运行了gather 命令?
  • 对不起。我的错。我的变量之一未正确命名。我喜欢你的回答并感谢你的帮助——我也喜欢@bouncyball 的回答。明天我会多玩它并接受一个。你确实教会了我很多东西——谢谢。现在请不要认为我无礼,但我已经过了睡觉时间了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-07
  • 2020-01-03
  • 2017-05-28
  • 2017-10-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多