---
title: "3-way crosstabs"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{crosstab3way}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r, include = FALSE}
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>"
)
```

```{r setup}
library(pollster)
library(dplyr)
library(knitr)
library(ggplot2)
```

It's common to want to view a crosstab of two variables by a third variable, for instance educational attainment by sex *and* marital status. The function `crosstab_3way` accomplishes this. Row and cell percents are both supported; column percents are not.

```{r}
illinois %>%
  # filter for recent years & limited ages
  filter(year > 2009,
         age > 39) %>%
  crosstab_3way(x = sex, y = educ6, z = maritalstatus, weight = weight,
                remove = c("widow/divorced/sep"),
                n = FALSE) %>%
  kable(digits = 0, caption = "Educational attainment by sex and marital status among Illinois residents ages 35+",
        format = "html")
```

Three-way crosstabs plot well as small multiples using ggplot facets.

```{r, fig.width=6, fig.height=4}
illinois %>%
  # filter for recent years & limited ages
  filter(year > 2009,
         age > 34) %>%
  crosstab_3way(x = sex, y = educ6, z = maritalstatus, weight = weight,
                remove = c("widow/divorced/sep"), 
                format = "long") %>%
  ggplot(aes(educ6, pct, fill = maritalstatus)) +
  geom_bar(stat = "identity", position = position_dodge()) +
  facet_wrap(facets = vars(sex)) +
  labs(title = "Educational attainment by sex and marital status",
       subtitle = "Illinois residents ages 40+") +
  theme(legend.position = "top")
```

The same plot can be made with margin of errors as well. (See the "crosstabs" vignette for a more detailed discussion of margin of errors.)


```{r, fig.width=6, fig.height=4}
illinois %>%
  # filter for recent years & limited ages
  filter(year > 2009,
         age > 34) %>%
  moe_crosstab_3way(x = sex, y = educ6, z = maritalstatus, weight = weight,
                remove = c("widow/divorced/sep"), format = "long") %>%
  ggplot(aes(educ6, pct, fill = maritalstatus)) +
  geom_bar(stat = "identity", position = position_dodge(),
           alpha = 0.5) +
  geom_errorbar(aes(ymin = (pct - moe), ymax = (pct + moe),
                    color = maritalstatus),
                position = position_dodge()) +
  facet_wrap(facets = vars(sex)) +
  labs(title = "Educational attainment by sex and marital status",
       subtitle = "Illinois residents ages 35+",
       caption = "Current Population Survey, 2010-2018") +
  theme(legend.position = "top")
```

### Special case, when the z-variable identifies survey waves

If the x-variable in your crosstab uniquely identifies survey waves for which the weights were independently generated, it is best practice to calculate the design effect independently for each wave. `moe_wave_crosstab_3way` does just that. All of the arguments remain the same as in `moe_crosstab_3way`.

```{r}
moe_wave_crosstab_3way(df = illinois, x = sex, y = educ6, z = year, weight = weight)
```
