Esta aula tem como principal referência bibliográfia o livro: Ciência de dados com o R: Introdução

OLIVEIRA, Paulo Felipe de; GUERRA, Saulo; MCDONNELL, Robert. Ciência de Dados com R - Introdução. Brasília: Editora IBPAD, 2018

ggplot2 package

O ggplot2 é mais um pacote desenvolvido por Hadley Wickham, o criador, por exemplo, do tidyr e do dplyr. A ideia do pacote, consiste em descrever um gráfico a partir dos seus componentes. Dessa forma, teoricamente, ficaria mais fácil entender a construção de gráficos mais complexos.

– Esse pacote é estruturado de forma que a “gramática” seja utilizada para um gráfico a partir de múltiplas camadas.

– As camadas serão formadas por dados, mapeamentos estéticos, transformações estatísticas dos dados, objetos geométricos (pontos, linhas, barras etc.) e ajuste de posicionamento.

– Além disso, existem outros componentes, como os sistemas de coordenadas (cartesiano, polar, mapa etc.) e, se for o caso, divisões do gráfico em subplots (facet). Um simples exemplo de múltiplas camadas seria um gráfico de pontos adicionado de uma curva de ajustamento.

Uma forma geral (template) para entender-se a estrutura do ggplot2, é a seguinte:

ggplot(data = <DATA>) + 
  <GEOM_FUNCTION>(
     mapping = aes(<MAPPINGS>),
     stat = <STAT>, 
     position = <POSITION>
  ) +
  <COORDINATE_FUNCTION> +
  <FACET_FUNCTION> # dividir o grafico em subplots

Dessa forma, incorporando essas observações, um template estendido seria o abaixo:

ggplot(data = <DATA>) + 
  <GEOM_FUNCTION>(
     mapping = aes(<MAPPINGS>),
     stat = <STAT>, 
     position = <POSITION>,
     data = <DATA> # pode receber os dados diretamente
  ) +
  <SCALE_FUNCTION> + # uma para cada elemento estético
  <COORDINATE_FUNCTION> +
  <FACET_FUNCTION> # dividir o gráfico em subplots

Informações sobre estado civil, grau de instrução, número de filhos, salário (expresso como fração do salário mínimo), idade (medida em anos e meses) e procedência de 36 empregados da seção de orçamentos da Companhia MB.

library(openxlsx)
## Warning: package 'openxlsx' was built under R version 4.3.3
url1 = "https://www.dropbox.com/scl/fi/u6ovzuozkb00s9hwx32c2/Tabela_Bus2.xlsx?rlkey=rnv7g4sz6zfknovverq57v3oi&dl=1"
dados <- openxlsx::read.xlsx(url1)
head(dados)
##   N Estado_Civil  Grau_de_Instrucao N_de_Filhos Salario_Min Idade
## 1 1     solteiro ensino fundamental          NA        4.00    26
## 2 2       casado ensino fundamental           1        4.56    32
## 3 3       casado ensino fundamental           2        5.25    36
## 4 4     solteiro       ensino médio          NA        5.73    20
## 5 5     solteiro ensino fundamental          NA        6.26    40
## 6 6       casado ensino fundamental           0        6.66    28
##   Regiao_de_Procedencia
## 1              interior
## 2               capital
## 3               capital
## 4                 outra
## 5                 outra
## 6              interior
require(ggplot2)
## Carregando pacotes exigidos: ggplot2
## Warning: package 'ggplot2' was built under R version 4.3.3
# Inicia o plot
g <- ggplot(dados)

# Adicionar pontos (geom_point) e
# vamos mapear variáveis a elementos estéticos dos pontos
# Size = 3 define o tamanho de todos os pontos
g <- g +
  geom_point(aes(x = Idade, y = Salario_Min, color = Estado_Civil),
             size = 3)

g

Altera a escala de cores

g <- g +
  scale_color_manual("Estado Civil",
                     values = c("red", "blue"),
                     labels = c("Casado", "Solteiro"))

# Rótulos (títulos)
g <- g +
  labs(title = 'Relação entre idade, salário mínimo e estado civil',
       y = 'Idade',
       x = 'Salário (R$)')

g

Note que o gráfico poderia ser criado com um bloco único de código:

ggplot(dados) +

geom_point(aes(x = Idade, y = Salario_Min, color = Estado_Civil),
           size = 3) +
  
scale_color_manual("Estado Civil",
                   values = c("red", "blue"),
                   labels = c("Casado", "Solteiro")) +
  
labs(title = 'Relação entre idade, salário mínimo e estado civil',
       y = 'Idade',
       x = 'Salário (R$)')

Nas próximas seções, falaremos com mais detalhes sobre cada componente, começando pelo mapeamento estético.

Mapeamento Estético

E quais são as características visuais de um objeto geométrico?

Como vimos no exemplo acima, mapeamos três variáveis para três características visuais de cada ponto: posição x, posição y e cor. Nos próximos exemplos, outros elementos estéticos serão utilizados, conforme o objeto geométrico selecionado.

Objetos geométricos

Tipo Objeto Geométrico
Dispersão (scatterplot) geom_point()
Gráfico de bolhas geom_point()
Gráfico de barras geom_bar() e geom_col()
Histograma geom_histogram()
Boxplot geom_boxplot()
Densidade geom_density()
Gráfico de linhas geom_line()

-Vamos, primeiramente, criar um gráfico com pontos a partir dos dados dos funcionários.

g1 <- ggplot(dados, aes(y = Idade, x = Salario_Min)) +
  geom_point()

g1

ggplot(dados, aes(y = Idade, x = Salario_Min)) +
  geom_point() +
  geom_smooth()
## `geom_smooth()` using method = 'loess' and formula = 'y ~ x'

Escalas

Veja o gráfico abaixo:

ggplot(dados, aes(x = Salario_Min, y = Idade, color = Grau_de_Instrucao)) +
  geom_point()

Note que a cor está mapeada para a variável Grau de Instrução.

ggplot(dados, aes(x = Salario_Min, y = Idade, color = Grau_de_Instrucao)) +
  geom_point() +
  scale_color_manual(values = c("orange", "black", "red"))

ggplot(dados, aes(x = Salario_Min, y = Idade, color = Grau_de_Instrucao)) +
  geom_point() +
  scale_color_manual(values = c("orange", "black", "red")) +
  scale_x_continuous(name = "Salário (R$)", breaks = seq(0,30,6)) + 
  scale_y_continuous(name = "Petal Width", breaks = seq(0,50,10), limits = c(0, 50))

Eixos

scale_x_continuous(name = waiver(), breaks = waiver(), minor_breaks = waiver(),
                   labels = waiver(), limits = NULL, expand = waiver(),
                   oob = censor, na.value = NA_real_, trans = "identity")

scale_y_continuous(name = waiver(), breaks = waiver(), minor_breaks = waiver(),
                   labels = waiver(), limits = NULL, expand = waiver(),
                   oob = censor, na.value = NA_real_, trans = "identity")
library(ISLR)
## Warning: package 'ISLR' was built under R version 4.3.3
data(Wage)
head(Wage)
##        year age           maritl     race       education             region
## 231655 2006  18 1. Never Married 1. White    1. < HS Grad 2. Middle Atlantic
## 86582  2004  24 1. Never Married 1. White 4. College Grad 2. Middle Atlantic
## 161300 2003  45       2. Married 1. White 3. Some College 2. Middle Atlantic
## 155159 2003  43       2. Married 3. Asian 4. College Grad 2. Middle Atlantic
## 11443  2005  50      4. Divorced 1. White      2. HS Grad 2. Middle Atlantic
## 376662 2008  54       2. Married 1. White 4. College Grad 2. Middle Atlantic
##              jobclass         health health_ins  logwage      wage
## 231655  1. Industrial      1. <=Good      2. No 4.318063  75.04315
## 86582  2. Information 2. >=Very Good      2. No 4.255273  70.47602
## 161300  1. Industrial      1. <=Good     1. Yes 4.875061 130.98218
## 155159 2. Information 2. >=Very Good     1. Yes 5.041393 154.68529
## 11443  2. Information      1. <=Good     1. Yes 4.318063  75.04315
## 376662 2. Information 2. >=Very Good     1. Yes 4.845098 127.11574

Descrição

ggplot(Wage, aes(x = age, y = wage, color = education)) +
  geom_point() +
  scale_x_continuous("Idade", breaks = seq(0, 80, 5),
                     expand = c(0, 5)) +
  scale_y_continuous("Salário", labels = function(x) paste0("US$ ", x),
                     limits = c(0, 400))

Para o eixo y, informamos que o nome do eixo é Salário, que os limites inferior e superior são 0 e 400 e alteramos os rótulos. No caso, passamos uma função que concatena US$ com o valor que já seria exibido.

Variáveis discretas

titanic <- read.csv2("C:/Users/eliasmedeiros/Dropbox/UFGD/2019_02_Disciplinas/Topicos_Estatistica_R/2_Aula/Dados_Aula_02/titanic.csv")
head(titanic)
##   PassengerId Survived Pclass
## 1           1        0     C3
## 2           2        1     C1
## 3           3        1     C3
## 4           4        1     C1
## 5           5        0     C3
## 6           6        0     C3
##                                                  Name    Sex Age SibSp Parch
## 1                             Braund, Mr. Owen Harris   male  22     1     0
## 2 Cumings, Mrs. John Bradley (Florence Briggs Thayer) female  38     1     0
## 3                              Heikkinen, Miss. Laina female  26     0     0
## 4        Futrelle, Mrs. Jacques Heath (Lily May Peel) female  35     1     0
## 5                            Allen, Mr. William Henry   male  35     0     0
## 6                                    Moran, Mr. James   male  NA     0     0
##             Ticket    Fare Cabin Embarked
## 1        A/5 21171  7.2500              S
## 2         PC 17599 71.2833   C85        C
## 3 STON/O2. 3101282  7.9250              S
## 4           113803 53.1000  C123        S
## 5           373450  8.0500              S
## 6           330877  8.4583              Q
ggplot(titanic, aes(x = Sex, y = Fare)) +
  geom_boxplot() + 
  scale_x_discrete("Sexo", labels = c("Feminino", "Masculino")) +
  labs(y = "Tarifa do passageiro")

ggplot(titanic, aes(x = Sex, y = Fare)) +
  geom_boxplot() + 
  scale_x_discrete("Sexo", limits = c("male", "female"),
                           labels = c("Masculino", "Feminino")) +
  labs(y = "Tarifa do passageiro")

titanic$sv <- ifelse(titanic$Survived==0, "Não Sobriviveu", "Sobreviveu")
ggplot(titanic, aes(x = sv , y = Age)) +
  geom_boxplot() + 
  scale_x_discrete("Survived") +
  labs(y = "Idade do passageiro")
## Warning: Removed 177 rows containing non-finite outside the scale range
## (`stat_boxplot()`).

Variáveis de Datas

library(readxl)
## Warning: package 'readxl' was built under R version 4.3.3
Dengue_MS_2017 <- readxl::read_xlsx("C:/Users/eliasmedeiros/Dropbox/UFGD/2019_02_Disciplinas/Topicos_Estatistica_R/2_Aula/Dados_Aula_02/Dengue_MS_2017.xlsx")

Quando estamos trabalhando com séries temporais, é comum que datas sejam associadas a algum eixo do grafico, geralmente ao eixo x. As funções padrão para controle de escalas dos eixos, para variáveis de datas, são as seguintes:

CG <- subset(Dengue_MS_2017, Municipio=="Campo Grande")
ggplot(CG, aes(x = Data, y = Notificacao)) +
  geom_line() 

ggplot(CG, aes(x = Data, y = Notificacao)) +
    geom_line() +
    scale_x_datetime(date_labels = "%b/%Y", date_breaks = "1 month")

Subplots (facet)

ggplot(Dengue_MS_2017, aes(x = Data, y = Notificacao)) +
  geom_line() +
  facet_wrap(vars(Municipio))+
  scale_x_datetime(date_labels = "%b/%Y", date_breaks = "1 month")+
  theme(axis.text.x = element_text(angle= 90 , vjust= .5 , hjust= 1)) 

ggplot(dados) +
 geom_point(aes(x = Idade, y = Salario_Min, color = Estado_Civil),
           size = 3)+
 facet_wrap(~ Grau_de_Instrucao)

ggplot(dados) +
 geom_point(aes(x = Idade, y = Salario_Min),
           size = 3)+
 facet_wrap(Estado_Civil ~ Grau_de_Instrucao)

Gráfico de Dispersão (geom_point())

Como queremos um gráfico de pontos, o objeto geométrico natural é o geom_point().

require(gapminder)
## Carregando pacotes exigidos: gapminder
## Warning: package 'gapminder' was built under R version 4.3.3
data(gapminder)
head(gapminder)
## # A tibble: 6 × 6
##   country     continent  year lifeExp      pop gdpPercap
##   <fct>       <fct>     <int>   <dbl>    <int>     <dbl>
## 1 Afghanistan Asia       1952    28.8  8425333      779.
## 2 Afghanistan Asia       1957    30.3  9240934      821.
## 3 Afghanistan Asia       1962    32.0 10267083      853.
## 4 Afghanistan Asia       1967    34.0 11537966      836.
## 5 Afghanistan Asia       1972    36.1 13079460      740.
## 6 Afghanistan Asia       1977    38.4 14880372      786.
gapminder1 <- subset(gapminder, year==max(year))

ggplot(gapminder1, aes(x = gdpPercap, y = lifeExp)) +
  geom_point() +
  labs(title = "Relação entre Renda per Capita e Expectativa de Vida - 2007",
       x = "Renda per Capita",
       y = "Expectativa de Vida")

ggplot(gapminder1, aes(x = gdpPercap, y = lifeExp)) +
  geom_point() + 
  scale_x_log10() +
  labs(title = "Relação entre Renda per Capita e Expectativa de Vida - 2007",
       x = "Renda per Capita (escala log 10)",
       y = "Expectativa de Vida")

ggplot(gapminder1, aes(x = gdpPercap, y = lifeExp, 
             color = continent, shape = continent)) +
  geom_point() + 
  scale_x_log10() +
  scale_color_discrete("Continente") +
  scale_shape_discrete("Continente") +
  labs(title = "Relação entre Renda per Capita e Expectativa de Vida - 2007",
       x = "Renda per Capita (escala log 10)",
       y = "Expectativa de Vida")

ggplot(gapminder1, aes(x = gdpPercap, y = lifeExp, 
             color = continent, shape = continent)) +
  geom_point(fill = "black", size = 3, stroke = 1) + 
  scale_x_log10() +
  scale_color_discrete("Continente") +
  scale_shape_manual("Continente", values = c(19, 21, 22, 23, 24)) +
  labs(title = "Relação entre Renda per Capita e Expectativa de Vida - 2007",
       x = "Renda per Capita (escala log 10)",
       y = "Expectativa de Vida")

Gráficos de Bolhas

ggplot(gapminder1, aes(x = gdpPercap, y = lifeExp, 
             size = pop)) +
  geom_point() + 
  scale_size_continuous("Populaçãoo (milhões)", 
                        labels = function(x) round(x/1000000)) +
  scale_x_log10() +
  labs(title = "Relação entre Renda per Capita e Expectativa de Vida - 2007",
       x = "Renda per Capita (escala log 10)",
       y = "Expectativa de Vida")

Gráficos de Barras

ggplot(dados, aes(x = Grau_de_Instrucao )) +
  geom_bar()

ggplot(Dengue_MS_2017, aes(x = Municipio, y = Notificacao)) +
  geom_col(fill = "dodgerblue") +
  labs(title = "Notificação de Dengue",
       subtitle = "2017",
       x = "Município",
       y = "Notificação")+
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

ggplot(Dengue_MS_2017, aes(x = reorder(Municipio, +Notificacao), y = Notificacao)) +
  geom_col(fill = "dodgerblue") +
  labs(title = "Notificação de Dengue",
       subtitle = "2017",
       x = "Município",
       y = "Notificação")+
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

ggplot(Dengue_MS_2017, aes(x = factor(Mes), y = Notificacao, fill = Municipio)) +
geom_col(position = "dodge") +
labs(title = "Notificação de Dengue em 2017",
     x = "Mês",
       y = "Notificação",
     fill = "Municipio")

Gráficos de linhas

Os gráficos de linhas são, geralmente, utilizados para apresentar-se a evolução de uma variável quantitativa em um intervalo de tempo.

ggplot(Dengue_MS_2017, aes(x = Mes, y = Notificacao, color = Municipio)) +
  geom_line() +
  scale_x_continuous(name = "Meses de 2017", breaks = 1:12)

ggplot(Dengue_MS_2017, aes(x = Mes, y = Notificacao, color = Municipio)) +
  geom_line() +
  scale_x_continuous(name = "Meses de 2017", breaks = 1:12)+
  geom_point(aes(shape = Municipio))

Histogramas e freqpoly

Os histogramas são utilizados para representar-se a distribuição de dados de uma variável quantitativa em intervalos contínuos.

ggplot(dados, aes(x = Salario_Min)) +
  geom_histogram(binwidth = 5, fill = 'dodgerblue',
                 color = 'black') +
  labs(title = "Distribuição do Salário Mínimo",
       x = "Anos",
       y = "Frequência") +
  theme_light()

ggplot(dados, aes(x = Salario_Min)) +
  geom_freqpoly(binwidth = 5)  +
  labs(title = "Distribuição do Salário Mínimo",
       x = "Anos",
       y = "Frequência") +
  theme_light()

ggplot(dados, aes(x = Salario_Min)) +
  geom_histogram(aes(y = ..count../sum(..count..)),
                 binwidth = 5, fill = 'dodgerblue',
                 color = 'black') +
  labs(title = "Distribuição do Salário Mínimo",
       x = "Anos",
       y = "Proporção") +
  theme_light()
## Warning: The dot-dot notation (`..count..`) was deprecated in ggplot2 3.4.0.
## ℹ Please use `after_stat(count)` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.

Boxplots

Por exemplo: qual é a distribuição do salário mínimo por estado civil?

ggplot(dados, aes(x = Estado_Civil, y = Salario_Min)) +
  geom_boxplot(fill = "dodgerblue") +
  labs(y = "Salário Mínimo",
       x = "Estado Civil",
       title = "Distribuição do salário mínimo por estado civil") 

Fazendo anotações

ggplot(dados, aes(x = Estado_Civil, y = Salario_Min)) +
  geom_boxplot(fill = "dodgerblue") +
   annotate("text", x = "solteiro", y = 18.5, label = "Anota Algo") +
  labs(y = "Salário Mínimo",
       x = "Estado Civil",
       title = "Distribuição do salário mínimo por estado civil")