多个类别相对频率条PLot

时间:2019-05-31 17:49:16

标签: r ggplot2 geom-bar

我想绘制多个频率相对比例条形图。这是我的类别:醉酒,醉酒,住房。看起来像这样:

housing: 1, 2, 3, 1, 4, 3, 1, 2
drunk: 1, 0, 1, 0, 0, 0, 0, 1
hsdrunk: 1, 0, 0, 1, 0, 0, 1, 1

我想按房屋类别绘制醉酒的比例频率,但也要按hsdrunk的值(1或0)分开。

我已经能够创建按房屋类别成比例的东西,但不确定如何添加“ hsdrunk”的其他类别。

png("Graphs/Analysis_Figure1.png")

analysis %>%  

 count(housing, drunk) %>% 

group_by(housing) %>% 

 mutate(freq = n/sum(n)) %>% 

 filter(drunk == 1) %>%

ggplot(aes(x = housing, y = freq, fill = drunk)) + 

geom_bar(stat="identity", position = 'dodge')

dev.off()

这是我想要的输出:

Desired Output

这是我到目前为止的结果:

Actual Output

1 个答案:

答案 0 :(得分:0)

我真的不希望您为此使用position = "dodge"。您会遇到钢筋宽度和间距甚至标签的麻烦。 ggplot2为此所做的是facet_grid()。然后,使它看起来像您想要的样子的大多数魔力发生在theme()中。

我将在下面介绍完整的解决方案。我真的希望您对ggplot2构建来处理此问题的方式有所了解(使用构面和主题元素)。在图形语法中,这种思维方式非常自然。

我将其扩展到了范围,目的是给您一些启发,说明如何可以用theme()完成。否则,坦率地说,您还能如何确定我的方向正确?主题元素以及ggplot2的其余部分在使用时变得更加直观。这是更多的练习时间。


这是您提供的数据。我将键添加到因子水平作为命名矢量(猜测:根据图的位置表示什么意思)。您会注意到我已经在一些换行符(\n)中烘焙到了房屋高度,以使绘制变得轻松而优美。

library(tidyverse)

analysis <- tribble(
  ~housing, ~drunk, ~hsdrunk,
         1,      1,        1,
         2,      0,        0,
         3,      1,        0,
         1,      0,        1,
         4,      0,        0,
         3,      0,        0,
         1,      0,        1,
         2,      1,        1
)
housing_levels <- c(
      `1` = "Not\nAlc.-Free",
      `2` = "Assigned"      ,
      `3` = "All\nAlc.-Free",
      `4` = "Requested"
)
hsdrunk_levels <- c(
      `0` = "Low HS Drinking",
      `1` = "High HS Drinking"
)

这是一个较小的调整,但是您的y轴标签非常具体:0表示为“ 0”,而小数没有前导0。您可以使用以下自定义函数来做到这一点:

label_y <- function(y) {
  y <- scales::number(y, accuracy = .1)
  y[y == "0.0"] <- "0"
  sub("0.", ".", y, fixed = TRUE)
}

我设置了您的条形颜色(为什么不设置),甚至查看了您的绘图背景色。在指定背景颜色时,我想让您知道一些细微差别。 (请参见下面的theme()部分。)

darkslategrey <- "#1a476f"
whitesmoke <- "#eaf2f3"

好的,让我们开始做生意。

  • recode_factor()是向量化switch()函数;神奇地将这些数字转换为您想要绘制的实际字符值。您可能不需要基本数据,但这对我很有用。 值得注意的是事实,要素水平的顺序确定页面上的顺序。通过使用recode_factor()而不是recode,我可以断言我在命名向量中设置的顺序。
  • 然后我group_by()高中的饮食和住房。由于drunk编码为1和0,因此很容易获得比例;只需使用mean(drunk)(不是这里有任何卑鄙的醉汉)。
  • 在对facet_grid()的呼叫中,我使用switch = "x"从顶部到底部“切换”标签位置。
  • 您可以使用housing的{​​{1}}参数来调整width级别之间的距离,并可以通过调用geom_bar()来调整hsdrunk组之间的距离。 expand_scale()scale_x_discrete()是一个很酷的功能;查阅expand_*_continuous()expand_scale()的文档以了解更多信息。您还可以使用主题元素expand_scale()来分隔组。但是由于以下原因,您无法这样做。
  • 您会在panel.spacing语句中看到一些细微的调整,设置中断并标记它们在“所需”绘图中的显示方式。
  • 我还添加了标题,在这里您会注意到,我不确定是否有肯定的方法可以将其与视觉中的对齐方式对齐。作为一个麻烦,它确实可以添加一堆空间,直到看起来正确为止。

就像我说的那样,大多数魔术都发生在scale_y_continuous()通话中。有许多方法可以做到这一点,包括从另一个基本主题开始然后从那里添加。所有这些选项都在theme() docs中进行了详细记录,但是如果我只是告诉您阅读这些文档,答案就不会太多了,对吗?我鼓励您在不使用任何theme()参数的情况下运行此代码,然后将它们一个接一个地添加并查看它们的作用。这是一个演练:

  • theme()strip.placementstrip.background标签放置在具有透明背景的x轴之外。
  • 是整个视觉图,它包含您hsdrunk中的所有内容。一个图可以具有1个或多个 panels 用于数据可视化;在您的情况下,有两个。 pngplot.background分别设置背景颜色。
  • 但是随后您就遇到了问题。 (注意这是我提到的关于背景颜色的细微差别。)两个白色面板是分开的,并且由于绘图背景是不同的颜色,所以分隔实际上是明显。为了使其看起来像您的“所需”图,请将panel.background设置为0,以使它们形成一个无缝的白色区域。当然,这也使您的组彼此相邻,但是我们已经使用panel.spacing进行了解决。
  • 尽管如此,您仍然没有任何面板网格线,因为基本网格是白色的。因此,将expand_scale()设置为与绘图背景相同的烟熏色。
  • panel.grid.major.y使您在x轴和y轴处得到黑线。您可能会尝试使用axis.line,但是panel.border会在面板的顶部,右侧甚至面板之间放置线条。
  • 您的y轴标签向侧面旋转!因此,您需要将其panel.border更改为90°。 angle将其居中于刻度线。
  • 说到刻度线,最终绘图中的x轴没有刻度线。因此,您需要使用hjust = .5删除它们。您可以用相同的方法删除x轴标题。
  • 最后,您的标题位于左侧,这是通过axis.ticks.x(水平对正)为0来完​​成的。
hjust

enter image description here

您可能不需要做所有这些争执,这取决于您要对这种期望的图尝试使用的字面量。特别是,如果您降低了背景色,并且您的数据中已经存在因子并且排序正确,则可以使自己更轻松。但是我希望您拥有提供的数据和参数,以达到既定目标所需的所有工具。编码愉快!