Um dos benefícios mais empoderadores de aprender Ciência de Dados com R é trabalhar de maneira simples e automatizada com dados abertos. Por exemplo, você já sentiu falta de ter acesso rápido a dados municipais de casos e óbitos de Covid-19? Dados nacionais e, até certo ponto, estaduais são mais simples. Contudo, para dados municipais há uma falta de ferramentas disponíveis que te permita, com poucos cliques, visualizar o gráfico de casos de um determinado município e até de comparar municípios diferentes. Veremos neste post como é simples fazer isso no R.
Obtendo os dados
Em virtude a um esforço coletivo e independente de profissionais de dados, principalmente jornalistas e programadores, o site Brasil-IO traz o seguinte dataset:
Graças a uma força-tarefa de 40 voluntários que, diariamente, compilam boletins epidemiológicos das 27 Secretarias Estaduais de Saúde, disponibilizamos uma base de dados com a série histórica de casos e óbitos confirmados por município. Embora essenciais para o planejamento de políticas de contenção do novo coronavírus, os dados municipais não têm sido divulgados pelo Ministério da Saúde. Ainda como parte desse esforço contínuo de fornecer dados úteis relacionados à pandemia, disponibilizamos outras bases estruturadas, como população dos municípios afetados, óbitos suspeitos registrados em cartório etc.
Você pode conhecer mais detalhes sobre os dados neste link.
Felizmente, como o link para download dos dados é fixo, o processo de download do arquivo pode ser feito dentro do próprio R com o código abaixo:
# baixar o dataset e salvar com o nome caso_full.csv.gz
download.file(“https://data.brasil.io/dataset/covid19/caso_full.csv.gz”, “caso_full.csv.gz”)
A partir disso, os dados já podem ser importados para o R:
library(tidyverse)
)
library(zoo) # calculo da media movel
df <- read_csv("caso_full.csv.gz"
Conhecendo os dados
Vejamos as colunas presentes no dataset:
glimpse(df)
## Rows: 1,466,848
## Columns: 18
## $ city <chr> "São Paulo", NA, "São P…
## $ city_ibge_code <dbl> 3550308, 35, 3550308, 3…
## $ date <date> 2020-02-25, 2020-02-25…
## $ epidemiological_week <dbl> 9, 9, 9, 9, 9, 9, 9, 9,…
## $ estimated_population <dbl> 12325232, 46289333, 123…
## $ estimated_population_2019 <dbl> 12252023, 45919049, 122…
## $ is_last <lgl> FALSE, FALSE, FALSE, FA…
## $ is_repeated <lgl> FALSE, FALSE, FALSE, FA…
## $ last_available_confirmed <dbl> 1, 1, 1, 1, 1, 1, 2, 2,…
## $ last_available_confirmed_per_100k_inhabitants <dbl> 0.00811, 0.00216, 0.008…
## $ last_available_date <date> 2020-02-25, 2020-02-25…
## $ last_available_death_rate <dbl> 0, 0, 0, 0, 0, 0, 0, 0,…
## $ last_available_deaths <dbl> 0, 0, 0, 0, 0, 0, 0, 0,…
## $ order_for_place <dbl> 1, 1, 2, 2, 3, 3, 4, 4,…
## $ place_type <chr> "city", "state", "city"…
## $ state <chr> "SP", "SP", "SP", "SP",…
## $ new_confirmed <dbl> 1, 1, 0, 0, 0, 0, 1, 1,…
## $ new_deaths <dbl> 0, 0, 0, 0, 0, 0, 0, 0,…
Veja que esse dataset possui dados tanto em nível municipal como estadual, indicado pela variável place_type. As colunas new_confirmed e new_deaths são as de nosso interesse.
Produzindo um gráfico
Vamos então ao nosso primeiro gráfico. Nele, quero plotar a curva de casos na cidade de São Paulo:
df %>%
filter(city == "São Paulo") %>%
ggplot(aes(x = date, y = new_confirmed)) +
geom_line() +
labs(x = NULL, y = "Casos",
title = "Quantidade de casos por dia na cidade de São Paulo")
E caso queiramos plotar a curva de óbitos:
df %>%
filter(city == "São Paulo") %>%
ggplot(aes(x = date, y = new_deaths)) +
geom_line() +
labs(x = NULL, y = "Óbitos",
title = "Quantidade de óbitos por dia na cidade de São Paulo")
Para juntar os dois gráficos acima em um só, podemos utilizar um recurso muito legal do ggplot2, os facets. Mas antes, é preciso mudar o formato dos dados por meio da função pivot_longer:
df_pivotado <- df %>%
filter(city == "São Paulo") %>%
select(date, new_confirmed, new_deaths) %>%
pivot_longer(cols = -date,
names_to = "var",
values_to = "quantidade")
head(df_pivotado)
## # A tibble: 6 x 3
## date var quantidade
## <date> <chr> <dbl>
## 1 2020-02-25 new_confirmed 1
## 2 2020-02-25 new_deaths 0
## 3 2020-02-26 new_confirmed 0
## 4 2020-02-26 new_deaths 0
## 5 2020-02-27 new_confirmed 0
## 6 2020-02-27 new_deaths 0
Com o dataset acima, podemos plotar tanto a quantidade de casos como a de óbitos em um só gráfico, separado por facets:
df_pivotado %>%
ggplot(aes(x = date, y = quantidade)) +
geom_line() +
facet_wrap(vars(var), ncol = 1, scales = "free_y") +
scale_x_date(date_breaks = "1 month", date_labels = "%Y/%m") +
labs(x = NULL, y = "Quantidade",
title = "Quantidade de casos e óbitos por dia na cidade de São Paulo")
Transformando para média móvel
É muito comum vermos nas notícias a curva de casos de Covid-19 sendo reportados como média móvel. Isso acontece porque dados diários tem grande variabilidade e porque, com médias móveis, é mais fácil visualizar movimentos de tendência de alta ou de queda.
Calcular a média móvel de 14 dias para cada cidade é algo simples de se fazer no R:
media_movel <- function(x) {zoo::rollmean(x, 14, fill = NA, align = "right")}
df_media_movel <- df %>%
filter(place_type == “city”) %>%
group_by(city) %>%
mutate(across(c(new_confirmed, new_deaths), media_movel)) %>%
ungroup()
Vejamos como fica o gráfico para São Paulo:
df_media_movel %>%
filter(city == "São Paulo") %>%
select(date, new_confirmed, new_deaths) %>%
pivot_longer(cols = -date,
names_to = "var",
values_to = "quantidade") %>%
ggplot(aes(x = date, y = quantidade)) +
geom_line() +
facet_wrap(vars(var), ncol = 1, scales = "free_y") +
scale_x_date(date_breaks = "1 month", date_labels = "%Y/%m") +
labs(x = NULL, y = "Quantidade",
title = "Média móvel de 14 dias de casos e óbitos por dia na cidade de São Paulo")
Veja como a média móvel suaviza a série temporal, reduzindo as variações abruptas e mostrando que Janeiro de 2021 tem apresentado uma forte tendência de alta.
Comparando diferentes cidades
Para comparar diferentes cidades, podemos dividir a média móvel de casos pela população da cidade:
df_media_movel %>%
filter(city %in% c("São Paulo", "Brasília", "Belo Horizonte", "Rio de Janeiro")) %>%
mutate(across(c(new_confirmed, new_deaths), function(x) x/estimated_population_2019)) %>%
ggplot(aes(x = date, y = new_confirmed, color = city)) +
geom_line()