pacman::p_load(dplyr, ggplot2)

1 Introdução e Dados

Os dados usados para fazer os boxplots são do seriado The Office (TidyTuesday)- semana 12 de 2020.

dados <- read.csv('https://raw.githubusercontent.com/rfordatascience/tidytuesday/master/data/2020/2020-03-17/office_ratings.csv')

glimpse(dados)
## Rows: 188
## Columns: 6
## $ season      <int> 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2~
## $ episode     <int> 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 1~
## $ title       <chr> "Pilot", "Diversity Day", "Health Care", "The Alliance", "~
## $ imdb_rating <dbl> 7.6, 8.3, 7.9, 8.1, 8.4, 7.8, 8.7, 8.2, 8.4, 8.4, 8.2, 8.2~
## $ total_votes <int> 3706, 3566, 2983, 2886, 3179, 2852, 3213, 2736, 2742, 2713~
## $ air_date    <chr> "2005-03-24", "2005-03-29", "2005-04-05", "2005-04-12", "2~

2 Criando um Boxplot único

Para variável x não colocamos nada, mas poderíamos inserir uma variável se quiséssemos fazer o bp por grupo.

ggplot(data = dados, aes(y = imdb_rating, x = "")) + #
  geom_errorbar(stat = "boxplot", width = 0.2) +  # A barra de erro é representada pela stat boxplot
  geom_boxplot(width = 0.3, fill = "darkolivegreen2",
               outlier.shape = 1, outlier.size = 2) +
  labs(y = "Avaliação no IMDB", x = "Todos os episódios") +
  theme_classic()

Outras modificações: Remover os outliers (color = NA)

ggplot(data = dados, aes(y = imdb_rating, x = "")) +
  geom_errorbar(stat = "boxplot", width = 0.2) +
  geom_boxplot(width = 0.3, fill = "cornsilk",
               outlier.color = NA) +
  labs(y = "Avaliação no IMDB", x = "Todos os episódios") +
  theme_classic()

2.1 Incluir a média

Poodemos incluir a média com a função geom_point() e usando stat = "summary", fun = "mean".

ggplot(data = dados, aes(y = imdb_rating, x = "")) +
  geom_errorbar(stat = "boxplot", width = 0.2) +
  geom_boxplot(width = 0.3, fill = "cornsilk",
               outlier.shape = 1, outlier.size = 2) +
  geom_point(stat = "summary", fun = "mean", shape = 4,
             size = 3, color = "blue") +
  labs(y = "Avaliação no IMDB", x = "Todos os episódios") +
  theme_classic()

2.2 Alterar o coeficiente

Vamos colocar os limites inferiores e superiores atarvés da multiplicação de um coeficiente pela amplitiude interquaartil. O boxplot de Tukey usa o coeficiente de 1.5.

ggplot(data = dados, aes(y = imdb_rating, x = "")) +
  geom_errorbar(stat = "boxplot", width = 0.2,
                coef = 2) +
  geom_boxplot(width = 0.3, fill = "grey90",
               outlier.shape = 1, outlier.size = 2,
               coef = 2) +
  labs(y = "Avaliação no IMDB", x = "Todos os episódios") +
  theme_classic()

2.3 Boxplot na horizontal

Às vezes podemos querer inverter os boxplot para horizontal. Usamos a função coord_flip() ajuda na visualização.

ggplot(data = dados, aes(y = imdb_rating, x = "")) +
  geom_errorbar(stat = "boxplot", width = 0.2) +
  geom_boxplot(width = 0.3, fill = "grey90",
               outlier.shape = 1, outlier.size = 2) +
  labs(y = "Avaliação no IMDB", x = "Todos os episódios") +
  coord_flip() +
  theme_classic()

2.4 Boxplot com jitter nos outliers

Às vezes precisamos evitar sobreposição de valores outliers. Para isso, usamos a camada geom_boxplot_jitter() do pacote ggrastr.

pacman::p_load(ggrastr)
ggplot(data = dados, aes(y = imdb_rating, x = "")) +
  geom_errorbar(stat = "boxplot", width = 0.2) +
  geom_boxplot_jitter(width = 0.3, fill="grey90",
                      outlier.shape = 1, outlier.size = 2,
                      outlier.jitter.height = 0,
                      outlier.jitter.width = 0.02) +
  labs(y = "Avaliação no IMDB", x = "Todos os episódios") +
    coord_flip() +
  theme_classic()

2.5 Boxplot com os pontos sobrepostos

Vamos sobrepor o boxplot com os pontos de dados. Ajustaremos uma transparência aos pontos e retiraremos a variação aaleatória na altura seja zero.

ggplot(data = dados, aes(y = imdb_rating, x = "")) +
  geom_errorbar(stat = "boxplot", width = 0.2) +
  geom_boxplot(width = 0.3, fill = "cornsilk",
               outlier.color = NA) +  # é preciso remover os outliers
  geom_jitter(alpha = 0.5, height = 0, width = 0.15, # Largura de 0.15 para cada lado
              size = 1.5) +
  labs(y = "Avaliação no IMDB", x = "Todos os episódios") +
  theme_classic()

2.6 Sobrepondo um gráfico de pontos (dotplot)

Vamos adicionar uma camada com um gráfico de pontos.

ggplot(data = dados, aes(y = imdb_rating, x = "")) +
  geom_errorbar(stat = "boxplot", width = 0.2) +
  geom_boxplot(width = 0.4, fill = "grey90",
               outlier.color = NA) +
  geom_dotplot(binaxis = "y",
               stackdir = "center",
               alpha = 0.4,
               dotsize = 0.6,
               binwidth = 0.1, #Pontos que diferem de 0.1 serão sobrepostos
               stackratio = 1.3) + # determina o espaçamentto entre os pontos
  labs(y = "Avaliação no IMDB", x = "Todos os episódios") +
  theme_classic()

3 Boxplot por grupos

Para variável x colocamos a variável categórica season, mas primeiro transformar para factor, pois ela é por origem inteira.

dados$season <- as.factor(dados$season)

ggplot(data = dados, aes(y = imdb_rating, x = season)) +
  geom_errorbar(stat = "boxplot", width = 0.2) +
  geom_boxplot(width = 0.4, fill = "grey90",
               outlier.shape = 1, outlier.size = 2) +
  labs(y = "Avaliação no IMDB", x = "Temporada") +
  theme_classic()

3.1 Cores diferentes para cada grupo

Podemos colorir as temporadas incluindo-a no aes() da funçãogeom_boxplot().

ggplot(data = dados, aes(y = imdb_rating, x = season)) +
  geom_errorbar(stat = "boxplot", width = 0.2) +
  geom_boxplot(aes(fill = season), width = 0.6,
               outlier.shape = 1, outlier.size = 2,
               show.legend = FALSE) +
  labs(y = "Avaliação no IMDB", x = "Temporada") +
  theme_classic()

3.2 Boxplot com dois fatores

Vamos primeiro criar uma segunda variável chamada frequencia de votos por temporada, ou seja, vamos fromar dois frupos dentro de uma mesma temporada, sendo um correspondedo aso espisódios com mais votos e outro episódios mais votados.

top <- dados %>% 
  group_by(season) %>% 
  slice_max(total_votes, prop = 0.5) %>% # Fatia os dados pela metade com mais votos
  mutate(freq_votes = "Mais votos")

bottom <- dados %>% 
  group_by(season) %>% 
  slice_min(total_votes, prop = 0.5) %>% # Fatia os dados pela metade com menos votos
  mutate(freq_votes = "Menos votos")

dados <- rbind(top, bottom)

Agora vamos fazer boxplot por dois grupos. É preciso separar as barras de erro e os boxplots usando o argumento position = position_dodge(width = 0.75)).

ggplot(data = dados, aes(y = imdb_rating, x = season,
                         fill = factor(freq_votes))) +
  geom_errorbar(stat = "boxplot", width = 0.3,
                position = position_dodge(width = 0.75)) +
  geom_boxplot(width = 0.6,
               outlier.shape = 1, outlier.size = 1.6,
               position = position_dodge(width = 0.75)) +
  labs(y = "Avaliação no IMDB", x = "Temporada", fill = NULL) +
  theme_classic() +
  theme(legend.position = "top")

4 Boxplot com geom_label

Podemos adicionar rótulo a alguns pontos específicos do gráfico com a função geom_label(). Vamos descobrir o maior valor e o menor valor.

maior <- dados %>%
  filter(season == "9") %>%
  slice_max(imdb_rating, n = 1)

menor <- dados %>%
  filter(season == "8") %>%
  slice_min(imdb_rating, n = 1)

min_max <- rbind(maior, menor)

Agora vamos fazer o gráfico e destacar esses dois pontos.

ggplot(data = dados, aes(y = imdb_rating, x = season)) +
  geom_errorbar(stat = "boxplot", width = 0.2) +
  geom_boxplot(aes(fill = season), width = 0.6,
               outlier.shape = 1, outlier.size = 2,
               show.legend = FALSE) +
  geom_label(data = min_max, aes(x = season,
                                 y = imdb_rating,
                                 label = title),
             size = 2.7, fill = "grey95",
             hjust = 0,
             position = position_nudge(x = 0.2),
             label.padding = unit(3.5, "pt")) +
  scale_x_discrete(expand = expansion(add = c(0.7, 1.5))) + # Expandir o eixo x para a esq e direita
  labs(y = "Avaliação no IMDB", x = "Temporada") +
  theme_classic()

5 Boxplot com asteriscos

Podemos destacar os níveis de significância sobre cada

pacman::p_load(ggsignif)

dados <- dados %>%
  mutate(Michael = case_when(as.numeric(season) < 8 ~ "Com Michael",
                             TRUE ~ "Sem Michael"))

?geom_signif

Fazendo o gráfico:

ggplot(data = dados, aes(y = imdb_rating, x = Michael,
                         fill = Michael)) +
  geom_errorbar(stat = "boxplot", width = 0.2) +
  geom_boxplot(width = 0.6,
               outlier.shape = 1, outlier.size = 2,
               show.legend = FALSE) +
  geom_signif(comparisons = list(c("Com Michael",
                                   "Sem Michael")),
              test = "wilcox.test",
              tip_length = 0.015,
              textsize = 4,
              annotations = c("*")) +
  labs(y = "Avaliação no IMDB", x = "") +
  theme_classic()