Este material foi elaborado para o curso extracurricular de Análise de Dados do DATASUS com R e RStudio realizado a cada semestre pelo curso de Medicina do UNIVAG e ministrado pelo Prof. Dr. Hugo Hoffmann, autor deste material.
Cooperando com os instrumentos oferecidos por este curso o aluno que se dedicar em compreender e replicar as análises aqui realizadas desenvolverá uma importante habilidade para o ambiente acadêmico, obterá maior independência para elaborar estudos epidemiológicos e aplicar o método científico para testar hipóteses utilizando o rigor estatístico exigido por periódicos científicos de alta qualidade.
Tenho recebido ótimos feedbacks das turmas que já passaram pelo curso, por isso, este material receberá constante ampliação e melhoria e, por isso, esta não é uma versão final. Aliás, a própria elaboração deste material foi uma sugestão que recebi dos meus alunos.
Foi criada uma pasta no Google Drive onde o aluno pode ter acesso à artigos científicos, bancos de dados utilizados durante o curso, vários ebooks, mapas conceituais, cheatsheets, scritps, tutoriais em vídeo e o cronograma, que você pode acessar neste link.
Sendo totalmente gratuito, o R é uma linguagem de programação orientada a objetos voltada à manipulação, análise e visualização de dados, criado por Ross Ihaka e Robert Gentleman no departamento de Estatística da Universidade de Auckland, Nova Zelândia.
O RStudio é um software livre que oferece um ambiente de desenvolvimento integrado para o R, ou seja, ele depende do R para executar suas funções, porém, oferece um ambiente que facilita sua utilização, o que é especialmente válido para usuários iniciantes.
Você pode usar o RStudio de duas formas, uma versão desktop (instalada no seu PC) ou uma versão web (na nuvem do RStudio). Para a primeira opção você precisa instalar primeiro o R e depois o RStudio.
Dica: Diferente do Epi Info, Stata e SPSS, no R todos os comandos são digitados em linhas de um script, logo, pequenos detalhes fazem a diferença entre um código funcional e uma mensagem vermelha de erro.
Pode você utilizar o R como calculadora:
## [1] 2
## [1] 6
## [1] 5
## [1] 25
Você pode criar vetores para armazenar dados, para isso utilizamos o sinal de atribuição <-, cujo atalho é [ALT]+[-]. A letrinha c minúscula é utilizada para quando desejamos combinar valores dentro de um vetor. Entenda vetores como variáveis ou características dos pacientes, já os dataframes (ou banco de dados) é uma coleção de vetores.
Digamos que temos os dados de 3 variáveis (idade, sexo, evoluacao)
para 5 pacientes coletados de um prontuário médico e desejamos inserir
estes dados diretamente no RStudio para analisarmos posteriormente. Para
isso, incluiríamos os seguintes vetores, os quais sexo
e
evolucao
serão armazenados como texto [chr], por isso as
aspas, e o vetor idade
armazenado como número [num].
Dica: Evite o uso de espaços e caracteres especiais nos nomes dos vetores.
Podemos reunir estes vetores e criar, a partir deles, um dataframe.
Depois de executado o código abaixo, no RStudio clique sobre o nome
dados
e você visualizará em uma nova aba o seu banco de
dados.
#-------- Criando o dataframe
dados <- data.frame(idade, sexo, evolucao)
#-------- Deletando os vetores
rm(idade, sexo, evolucao)
idade | sexo | evolucao |
---|---|---|
23 | Feminino | Cura |
45 | Feminino | Óbito |
32 | Masculino | Óbito |
57 | Masculino | Cura |
28 | Feminino | Cura |
A função str
nos permite visualizar o nome das variáveis
e o tipo do dado armazenado.
## 'data.frame': 5 obs. of 3 variables:
## $ idade : num 23 45 32 57 28
## $ sexo : chr "Feminino" "Feminino" "Masculino" "Masculino" ...
## $ evolucao: chr "Cura" "Óbito" "Óbito" "Cura" ...
Essa informação será útil para realizarmos a estatística descritiva, pois cada tipo de variável deve ser analisada estatisticamente conforme sua natureza:
Variável | Estatística Descritiva |
---|---|
Categórica | Frequências (n, %) |
Numérica | Média ou Medianas |
Agora podemos realizar algumas análises básicas, primeiro, a frequência a evolução:
##
## Cura Óbito
## 3 2
Inclusive, podemos gerar um gráfico de barras:
barplot(table(dados$evolucao),
col = "steelblue",
xlab = "Evolução do paciente",
ylab = "Frequência",
main = "Distribuição dos casos segundo evolução do paciente")
Ou um boxplot:
Tão importante quanto saber analisar os dados é conseguir extrair
deles informação, ou seja, realizar sua interpretação. O gráfico acima é
um dos mais utilizados em pesquisas médicas e representa diferentes
informações em sua anatomia. A linha preta mais forte situada dentro da
caixa representa a mediana, que você pode confirmar executando
median(dados$idade)
. A linha inferior (abaixo da caixa)
representa o menor valor da idade, confirme o valor executando
min(dados$idade)
e a linha superior (acima da caixa)
representa o maior valor da idade, verifique isso com
max(dados$idade)
. Há mais informações neste gráfico, mas
por enquanto temos o suficiente para um conhecimento introdutório.
Até agora já realizamos estatística descritiva de de uma variável categórica e uma numérica, plotamos um gráfico de barras e um boxplot, porém, fizemos tudo isso com funções nativas (pré-instaladas) do R. Mas o que faz dele uma linguagem tão versátil é a enorme comunidade de usuários que cria novas funções e disponibiliza isso para toda comunidade utilizar. As funções são compartilhadas em pacotes, ou seja, um pacote é uma coleção de funções criadas por alguém que decidiu compartilhar seu conhecimento e ajudar outros usuários do R. Legal isso né?
Os pacotes são instalados apenas uma vez no seu PC e você pode consultá-los na aba Packages no canto direito inferior do RStudio, ao lado da aba Plots, onde visualizamos nosso gráfico agora pouco.
Você pode instalar pacotes executando o comando
install.packages("nomedopacote")
ou clicando no notão
Install presente na aba Packages e digitando ali o nome
do pacote a ser instalado. Para o nosso curso precisamos instalar os
seguintes pacotes:
install.packages("tidyverse") # Coleção de funções importantes
install.packages("readxl") # Importa dados de planilhas do Excel
install.packages("read.dbc") # Importa dados do DATASUS
install.packages("DescTools") # Análise estatística descritiva e inferencial
install.packages("ggstatsplot") # Gráficos estatísticos para artigos científicos
install.packages("gtsummary") # Tabela de análises para o artigo cientifico
install.packages("hrbrthemes") # Possui temas belíssimos para gráficos
Não se preocupe com as letrinhas subindo no console, o R vai se conectar na internet para baixar os pacotes e fazer a instalação. Caso ainda tenha dúvida, assista este tutorial.
É uma boa prática, especialmente para iniciantes em R, definir uma
pasta no seu computador como o local onde colocaremos todos os bancos de
dados que desejamos realizar a importação para o R. Recomendo que você
crie uma pasta chamada R no C:
do seu computador,
depois execute este código:
Dica: Tenho um tutorial que pode te ajudar, se ainda estiver com dúvida: assista.
Para este exemplo, acesse este link do Portal Dados Abertos e baixe a planilha Agosto de 2018 clicando em Acessar o recurso. Esta planilha possui servidores do poder executivo federal que aderiram a um programa de desligamento voluntário. Salve esta planilha com o nome “Desligamento.xlsx” no seu diretório de trabalho e então execute o código abaixo:
Há duas formas de importar dados no R, a primeira é colocando apenas
o nome do arquivo quando temos definido um diretório de trabalho (que
foi o que fizemos antes) e a segunda, quando não temos um diretório
definido, é informando o caminho completo ao arquivo, que seria
C:/R/Desligamento.xslx
.
Dica: O nome dados
é você quem escolhe
e poderia ser outro, o ideal é que seja curto porque economiza tempo.
Ninguém vai querer colocar algo desse tipo
meus_dados_do_TCC_da_faculdade
. Você saberá que deu tudo
certo quando o nome do dataframe aparecer na aba Environment no
canto direito superior do RStudio. Inclusive, você pode clicar sobre o
nome dados
para visualizar seu dataframe.
Este é o arquivo chamado de Comma-separated values ou valores separados por vírgulas, sendo um padrão muito utilizado para disponbilização de dados abertos. Para este exemplo, utilizaremos dados de casos humanos de febre amarela entre 1994 e 2001 disponibilizados no Portal de Dados Abertos, que você fará download ao clicar em Acessar o recurso, agora salve o arquivo com o nome “febre_amarela.csv” no seu diretório de trabalho e então execute o código abaixo:
Dica: O caminho no Windows usa essa barra
\
que você deve substituir por esta barra
/
.
Se a planilha (Excel ou CSV) estiver disponível em um link público, podemos importar diretamente no R sem nem ter que fazer o download dos dados para o computador. Para este exemplo, iremos baixar os dados de casos, hospitalizações e óbitos diários por COVID-19 em residentes de Nova Iorque (EUA) que estão disponíveis para acesso público no repositório de dados da cidade NYC OpenData.
Dica: O mais observadores terão percebido que no
exemplo anterior utilizamos a função read.csv2
e agora
utilizamos a função read.csv
. Sim, há o momento certo de
utilizarmos cada uma delas. A primeira função serve para importar dados
em CSV em formato brasileiro e a segunda para planilhas CSV em formato
estrangeiro. Isso é necessário porque o separador de decimal no formato
brasileiro é vírgula, mas no estrangeiro é ponto.
Microdados do DATASUS são armazenados em formato Database Files Compressed, é um formato que necessitaria de aplicativos específicos para seres visualizados, como o aplicativo oficial de análise do DATASUS chamado TabWin. No R podemos fazer de duas formas:
Para este exemplo acessaremos o site https://datasus.saude.gov.br, depois clicarmos em “Acesso à informação”, rolar a tela mais para baixo e clicar em “Serviços”, depois clicar em “Transferência / Download de Arquivos” e então em “Transferência de Arquivos”. Caso não consiga encontrar, clique aqui e faça as seguintes seleções:
Seção | Opção que você deve selecionar |
---|---|
Fonte | SIHSUS - Sistema de Informações Hospitalares do SUS |
Modalidade | Dados |
Tipo de Arquivo | RD - AIH Reduzida |
Ano | 2023 |
Mês | Janeiro |
UF | MT |
Com essa configuração faremos o download de internações hospitalares atendidas pelo SUS e ocorridas em todo estado de Mato Grosso em janeiro de 2023. Para isso, clique em Enviar, depois em “Download” e, por fim, no link “arquivo.zip” para fazer o download. Salve-o no seu diretório de trabalho, descompacte o banco de dados RDMT2301.dbc e execute o código abaixo no R:
Dica: Você pode realizar múltiplas seleções ao segurar a tecla CTRL do teclado e clicar sobre outros anos, meses ou unidades da federação.
Para realizar uma importação direta precisamos seguir alguns passos a mais do que temos feito até então, veja como fazer. Iremos baixar o mesmo banco de dados do exemplo anterior.
#-------- Etapa 1 - Criar um arquivo temporário
temp <- tempfile()
#-------- Etapa 2 - Download do arquivo direto do servidor do DATASUS
download.file("ftp://ftp.datasus.gov.br/dissemin/publicos/SIHSUS/200801_/Dados/RDMT2301.dbc", temp, mode = "wb")
#-------- Etapa 3 - Importar o banco de dados
dados <- read.dbc(temp)
#-------- Etapa 4 - Remover o arquivo temporário
rm(temp)
Descobrimos que houveram um total de 16641 internações hospitalares
atendidas pela rede SUS no estado de Mato Grosso em janeiro de 2023. E
se quiséssemos baixar dados de fevereiro de 2015 para o Paraná? Perceba
que o nome do arquivo identifica o tipo de informação RD (AIH’s
Aprovadas), depois MT a unidade da federação, então 23
do ano e 01 do mês. Logo, para baixar estes dados manteríamos
todo o link da “Etapa 2” substituindo apenas a parte
RDMT2301
por RDPR1501
.
De posse dos dados do nosso estudo, vamos conhecer as variáveis que
este banco de dados possui utilizando a função glimpse
que
lista o nome das variáveis, apresenta o tipo que elas foram armazenadas
e nos dá algunas exemplos de seu preenchimento:
## Rows: 16,641
## Columns: 113
## $ UF_ZI <fct> 510000, 510000, 510000, 510000, 510000, 510000, 510000, 510…
## $ ANO_CMPT <fct> 2023, 2023, 2023, 2023, 2023, 2023, 2023, 2023, 2023, 2023,…
## $ MES_CMPT <fct> 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01,…
## $ ESPEC <fct> 02, 02, 02, 03, 03, 03, 03, 03, 03, 03, 03, 03, 03, 03, 03,…
## $ CGC_HOSP <fct> 32944118000164, 32944118000164, 32944118000164, 32944118000…
## $ N_AIH <fct> 5123100971648, 5123100971714, 5123100971725, 5122103685017,…
## $ IDENT <fct> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,…
## $ CEP <fct> 78545000, 78552220, 78540000, 78556334, 35550000, 78559609,…
## $ MUNIC_RES <fct> 510724, 510790, 510305, 510790, 313350, 510790, 510790, 510…
## $ NASC <fct> 20010919, 19910804, 19930408, 19650917, 19720630, 20010412,…
## $ SEXO <fct> 3, 3, 3, 3, 1, 3, 3, 1, 3, 3, 3, 3, 3, 1, 3, 1, 1, 1, 1, 1,…
## $ UTI_MES_IN <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ UTI_MES_AN <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ UTI_MES_AL <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ UTI_MES_TO <int> 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ MARCA_UTI <fct> 00, 00, 00, 75, 00, 00, 00, 00, 00, 00, 75, 00, 00, 00, 00,…
## $ UTI_INT_IN <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ UTI_INT_AN <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ UTI_INT_AL <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ UTI_INT_TO <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ DIAR_ACOM <int> 3, 2, 3, 0, 0, 0, 2, 2, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0,…
## $ QT_DIARIAS <int> 3, 2, 3, 3, 1, 3, 2, 2, 4, 3, 5, 1, 2, 2, 1, 2, 31, 8, 4, 6…
## $ PROC_SOLIC <fct> 0411010034, 0411010034, 0411010034, 0303030038, 0305020056,…
## $ PROC_REA <fct> 0411010034, 0411010034, 0411010034, 0303030038, 0305020056,…
## $ VAL_SH <dbl> 419.68, 417.68, 513.96, 3441.95, 380.93, 193.71, 969.79, 96…
## $ VAL_SP <dbl> 276.43, 276.43, 276.43, 590.01, 68.72, 23.99, 146.21, 146.2…
## $ VAL_SADT <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ VAL_RN <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ VAL_ACOMP <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ VAL_ORTP <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ VAL_SANGUE <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ VAL_SADTSR <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ VAL_TRANSP <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ VAL_OBSANG <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ VAL_PED1AC <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ VAL_TOT <dbl> 696.11, 694.11, 790.39, 4031.96, 449.65, 217.70, 1116.00, 1…
## $ VAL_UTI <dbl> 0, 0, 0, 3600, 0, 0, 0, 0, 0, 0, 1200, 0, 0, 0, 0, 0, 0, 0,…
## $ US_TOT <dbl> 133.86, 133.48, 151.99, 775.37, 86.47, 41.86, 214.61, 214.6…
## $ DT_INTER <fct> 20230115, 20230117, 20230117, 20221228, 20230107, 20230123,…
## $ DT_SAIDA <fct> 20230118, 20230119, 20230120, 20230105, 20230108, 20230126,…
## $ DIAG_PRINC <fct> O619, O820, O159, E108, N180, O998, C188, C168, C188, O200,…
## $ DIAG_SECUN <fct> 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000,…
## $ COBRANCA <fct> 61, 61, 62, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,…
## $ NATUREZA <fct> 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,…
## $ NAT_JUR <fct> 3069, 3069, 3069, 3069, 3069, 3069, 3069, 3069, 3069, 3069,…
## $ GESTAO <fct> 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,…
## $ RUBRICA <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ IND_VDRL <fct> 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0,…
## $ MUNIC_MOV <fct> 510790, 510790, 510790, 510790, 510790, 510790, 510790, 510…
## $ COD_IDADE <fct> 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,…
## $ IDADE <int> 21, 31, 29, 57, 50, 21, 72, 64, 54, 41, 27, 25, 28, 73, 38,…
## $ DIAS_PERM <int> 3, 2, 3, 8, 1, 3, 2, 2, 4, 3, 6, 1, 2, 2, 1, 2, 30, 8, 4, 6…
## $ MORTE <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ NACIONAL <fct> 010, 010, 010, 010, 010, 010, 010, 010, 010, 010, 010, 010,…
## $ NUM_PROC <fct> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
## $ CAR_INT <fct> 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02, 02,…
## $ TOT_PT_SP <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ CPF_AUT <fct> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
## $ HOMONIMO <fct> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ NUM_FILHOS <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ INSTRU <fct> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ CID_NOTIF <fct> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
## $ CONTRACEP1 <fct> 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,…
## $ CONTRACEP2 <fct> 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,…
## $ GESTRISCO <fct> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,…
## $ INSC_PN <fct> 000000000000, 000000000000, 000000000000, 000000000000, 000…
## $ SEQ_AIH5 <fct> 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000,…
## $ CBOR <fct> 000000, 000000, 000000, 000000, 000000, 000000, 000000, 000…
## $ CNAER <fct> 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000, 000,…
## $ VINCPREV <fct> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ GESTOR_COD <fct> 00011, 00011, 00011, 00007, 00007, 00007, 00007, 00007, 000…
## $ GESTOR_TP <fct> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0,…
## $ GESTOR_CPF <fct> 000093983018068, 000093983018068, 000093983018068, 00009398…
## $ GESTOR_DT <fct> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
## $ CNES <fct> 2795671, 2795671, 2795671, 2795671, 2795671, 2795671, 27956…
## $ CNPJ_MANT <fct> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
## $ INFEHOSP <fct> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
## $ CID_ASSO <fct> 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000,…
## $ CID_MORTE <fct> 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000,…
## $ COMPLEX <fct> 02, 02, 02, 02, 02, 02, 03, 03, 03, 02, 02, 02, 02, 03, 02,…
## $ FINANC <fct> 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06, 06,…
## $ FAEC_TP <fct> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
## $ REGCT <fct> 7102, 7102, 7102, 7102, 7102, 7102, 7104, 7104, 7104, 7102,…
## $ RACA_COR <fct> 03, 03, 01, 03, 03, 03, 03, 03, 01, 01, 03, 03, 01, 02, 03,…
## $ ETNIA <fct> 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000, 0000,…
## $ SEQUENCIA <int> 3830, 3831, 3832, 3942, 3943, 3944, 3946, 3947, 3948, 4054,…
## $ REMESSA <fct> HE51000001N202301.DTS, HE51000001N202301.DTS, HE51000001N20…
## $ AUD_JUST <fct> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
## $ SIS_JUST <fct> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
## $ VAL_SH_FED <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ VAL_SP_FED <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ VAL_SH_GES <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ VAL_SP_GES <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ VAL_UCI <dbl> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ MARCA_UCI <fct> 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00,…
## $ DIAGSEC1 <fct> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
## $ DIAGSEC2 <fct> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
## $ DIAGSEC3 <fct> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
## $ DIAGSEC4 <fct> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
## $ DIAGSEC5 <fct> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
## $ DIAGSEC6 <fct> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
## $ DIAGSEC7 <fct> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
## $ DIAGSEC8 <fct> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
## $ DIAGSEC9 <fct> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
## $ TPDISEC1 <fct> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,…
## $ TPDISEC2 <fct> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ TPDISEC3 <fct> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ TPDISEC4 <fct> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ TPDISEC5 <fct> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ TPDISEC6 <fct> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ TPDISEC7 <fct> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ TPDISEC8 <fct> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
## $ TPDISEC9 <fct> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,…
Nosso estudo avaliará indivíduos com idade maior ou igual a 20 anos, do sexo masculino, hospitalizados por infarto agudo do miocárdio em Mato Grosso durante o mês de janeiro de 2023 e incluirá as seguintes variáveis:
Variáveis | Descrição |
---|---|
MES_CMPT | Mês da internação |
CAR_INT | Caráter da internação |
DIAS_PERM | Tempo de internação (dias) |
VAL_TOT | Valor da internação (R$) |
MORTE | Evolução |
Para isso precisaremos realizar transformações neste banco de dados para que tenhamos o recorte de nosso interesse.
A função filter
é útil para inserirmos os critérios de
inclusão de nosso estudo. Observe que após a execução do código abaixo o
tamanho de amostra será reduzido para n=93, que foram as
internações que respeitaram o critérios que estabelecemos.
dados <- dados |>
filter(COD_IDADE == "4", # Idade em anos completos
IDADE >= 20, # Idade de 20 anos ou mais
SEXO == "1", # Sexo masculino
DIAG_PRINC == "I219") # CID-10 de infarto agudo do miocárdio
Dica: Usamos agora o sinal pipe ao final da primeira linha, que pode ocorrer também neste outro formato: %>%. Ele pode ser inserido apertando simultaneamente no teclado as teclas CTRL+SHIFT+M e serve para informar ao código que ele continuará executando a próxima linha (debaixo recuada).
Entretanto, nosso banco de dados ainda continua com 113 variáveis, mas queremos apenas aquelas que estão na tabela acima e para isso executaremos o seguinte código:
Agora nosso banco de dados está quase pronto para análise, só precisamos rotular as categorias das variáveis não numéricas para que saibamos o que significa cada categoria da variável. Neste momento, é muito útil consultarmos um Dicionário de Dados. No caso do SIH, podemos consultar este.
Assim descobrimos que para a variável MORTE
“0”
significa “Alta” e “1” significa “Óbito” por exemplo. Agora precisamos
escrever um código que faça essa transformação. Usaremos a função
mutate
e dentro dela iremos modificar todas as variáveis
que precisarmos:
dados <- dados |>
mutate(CAR_INT = case_when(CAR_INT == "01" ~ "Eletivo",
CAR_INT == "02" ~ "Urgência"),
MORTE = case_when(MORTE == 0 ~ "Alta",
MORTE == 1 ~ "Óbito"))
Dica: Um único sinal de igual no R significa
atribuição, da mesma forma que o sinal já visto anteriormente
<-
, mas dois sinais de igual são usados para igualdade,
usado em condicionais como fizemos antes com a função
filter
e agora com a função case_when
.
Outro detalhe que você deve ficar atento é ao tipo da variável, observe que a variável MORTE está armazenada como número, diferentemente da variável CAR_INT que está como factor. Exatamente por isso é que precisamos colocar o número entre aspas (texto) em CAR_INT, mas sem aspas (número) em MORTE.
Dica: Observe que ao final de cada função inserimos
o sinal de pipe para que a função da linha abaixo seja executada na
sequência. Sequência, aliás, é a palavra chave aqui, porque ela altera
sim o funcionamento das coisas. Por exemplo, se você não selecionasse a
variável MORTE em select
seria retornado um erro porque a
função mutate
não encontraria nenhuma variável com este
nome para modificar.
Também é possível alterar o nome das variáveis para um que melhore
nossa compreensão do tipo de informação que ele armazena. Se queremos,
entre outras coisas, renomear a variável MORTE
para
EVOLUCAO
, então faríamos assim:
dados <- dados |>
rename("EVOLUCAO" = "MORTE",
"MES" = "MES_CMPT",
"TEMPO" = "DIAS_PERM",
"VALOR" = "VAL_TOT",
"CARATER" = "CAR_INT")
Vejamos o resultado:
## Rows: 93
## Columns: 5
## $ MES <fct> 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 01, 0…
## $ CARATER <chr> "Urgência", "Urgência", "Urgência", "Urgência", "Urgência", "…
## $ TEMPO <int> 12, 0, 2, 3, 30, 5, 2, 9, 1, 17, 1, 6, 7, 1, 4, 2, 3, 7, 1, 7…
## $ VALOR <dbl> 4885.56, 1194.47, 589.12, 1883.32, 906.07, 588.12, 588.12, 32…
## $ EVOLUCAO <chr> "Alta", "Óbito", "Alta", "Alta", "Alta", "Alta", "Alta", "Alt…
Podemos usar o pipe (|>
ou %>%
) para
encadear tudo que fizemos nos passos anteriores em apenas um bloco de
código. Ficaria assim:
dados <- dados |>
filter(COD_IDADE == "4",
IDADE >= 20,
SEXO == "1",
DIAG_PRINC == "I219") |>
select(MES_CMPT, CAR_INT, DIAS_PERM, VAL_TOT, MORTE) |>
mutate(CAR_INT = case_when(CAR_INT == "01" ~ "Eletivo",
CAR_INT == "02" ~ "Urgência"),
MORTE = case_when(MORTE == 0 ~ "Alta",
MORTE == 1 ~ "Óbito")) |>
rename("EVOLUCAO" = "MORTE",
"MES" = "MES_CMPT",
"TEMPO" = "DIAS_PERM",
"VALOR" = "VAL_TOT",
"CARATER" = "CAR_INT")
Temos nosso banco de dados organizado e pronto para iniciarmos a
produção dos resultados da nossa pesquisa. Vamos utilizar a função
Desc
do pacote DescTools
para gerarmos uma
tabela com a frequência dos óbitos:
## ------------------------------------------------------------------------------
## dados$EVOLUCAO (character - dichotomous)
##
## length n NAs unique
## 93 93 0 2
## 100.0% 0.0%
##
## freq perc lci.95 uci.95'
## Alta 88 94.6% 88.0% 97.7%
## Óbito 5 5.4% 2.3% 12.0%
##
## ' 95%-CI (Wilson)
A função produziu um resultado no console e também um gráfico.
Diferentemente da função básica
table
que utilizamos
anteriormente, temos numa mesma saída várias informações muito
úteis:
Descobrimos que a letalidade hospitalar por infarto agudo do miocárdio foi igual a 5,4% entre homens com idade de 20 anos ou mais em Mato Grosso em janeiro de 2023.
Uma coisa boa desta função é você pode utilizá-la para qualquer tipo de variável que a própria função faz a estatística adequada para diferentes tipos de variáveis. Vejamos o output para uma variável numérica:
## ------------------------------------------------------------------------------
## dados$TEMPO (integer)
##
## length n NAs unique 0s mean meanCI'
## 93 93 0 22 4 6.19 4.79
## 100.0% 0.0% 4.3% 7.59
##
## .05 .10 .25 median .75 .90 .95
## 1.00 1.00 2.00 4.00 7.00 17.80 23.40
##
## range sd vcoef mad IQR skew kurt
## 30.00 6.80 1.10 2.97 5.00 1.86 2.76
##
## lowest : 0 (4), 1 (13), 2 (14), 3 (15), 4 (7)
## highest: 23, 24 (2), 27, 28, 30
##
## heap(?): remarkable frequency (16.1%) for the mode(s) (= 3)
##
## ' 95%-CI (classic)
Agora temos outras informações igualmente úteis:
Como você redigiria este resultado no seu artigo? Algo mais ou menos assim: O tempo médio de internação hospitalar por infarto agudo do miocárdio foi igual a 6,19 dias (IC95%=4,79-7,59) entre indivíduos do sexo masculino, com idade de 20 anos ou mais atendidos em Mato Grosso em janeiro de 2023.
Dica: No gráfico gerado para a variável numérica você observará um boxplot deitado, a interpretação dele é a mesma daquele outro que geramos anteriormente.
Agora iremos utilizar a função tbl_summary
para gerar
nossa tabela descritiva de perfil epidemiológico:
dados |>
tbl_summary(missing_text = "Não informado",
label = list(MES ~ "Mês da internação",
CARATER ~ "Caráter da internação",
TEMPO ~ "Tempo de internação (dias)",
VALOR ~ "Custo da internação (R$)",
EVOLUCAO ~ "Evolução"),
digits = list(all_categorical() ~ c(0, 2))) |>
bold_labels()
Characteristic | N = 931 |
---|---|
Mês da internação | |
01 | 93 (100.00%) |
Caráter da internação | |
Eletivo | 2 (2.15%) |
Urgência | 91 (97.85%) |
Tempo de internação (dias) | 4 (2, 7) |
Custo da internação (R$) | 2,570 (613, 5,996) |
Evolução | |
Alta | 88 (94.62%) |
Óbito | 5 (5.38%) |
1 n (%); Median (IQR) |
O argumento missing_text
serve para nos informar quantos
indivíduos não tiveram informações preenchidas para cada variável, em
nosso exemplo, não houveram dados ausentes, label
serve
para descrevermos melhor o nome da variável e digits
nos
permite definir a quantidade de casas decimais.
Dica: Você pode adicionar algumas linhas de código para o R gerar essa tabela diretamente dentro de um arquivo do Word, veja o exemplo abaixo:
dados |>
tbl_summary(missing_text = "Não informado",
label = list(MES ~ "Mês da internação",
CARATER ~ "Caráter da internação",
TEMPO ~ "Tempo de internação (dias)",
VALOR ~ "Custo da internação (R$)",
EVOLUCAO ~ "Evolução"),
digits = list(all_categorical() ~ c(0, 2))) |>
bold_labels() |>
as_flex_table() |>
flextable::save_as_docx(path = "Tabela1.docx")
Vamos agora gerar um gráfico de colunas para internações segundo evolução do paciente:
dados |>
group_by(EVOLUCAO) |> # Agrupa o total de casos
summarise(total = n()) |> # Conta o total de linhas
ggplot(aes(y = total, x = EVOLUCAO)) + # Define a estética do gráfico
geom_col() + # Executa um gráfico de coluna
theme_ipsum_ps() + # Insere um tema
labs(title = "Internações segundo evolução do paciente",
subtitle = "Infarto agudo do miocárdio entre homens de 20 anos ou mais",
y = "Total de internações",
x = "Evolução",
caption = "Fonte: SIH-DATASUS, Mato Grosso, Janeiro/2023")
E se quisermos estratificar o gráfico acima pelo caráter da internação?
dados |>
group_by(EVOLUCAO, CARATER) |>
summarise(total = n()) |>
ggplot(aes(y = total, x = EVOLUCAO, fill = CARATER)) +
geom_col(position = "dodge") +
theme_ipsum_ps() +
labs(title = "Internações segundo evolução do paciente",
subtitle = "Infarto agudo do miocárdio entre homens de 20 anos ou mais",
y = "Total de internações",
x = "Evolução",
caption = "Fonte: SIH-DATASUS, Mato Grosso, Janeiro/2023",
fill = "Caráter da internação")
Adicionamos uma segunda variável dentro da função
group_by
e depois a colocamos dentro da estética do gráfico
com o argumento fill
. Dentro da função
geom_col
adicionamos o argumento “dodge” para dizer que
queremos uma coluna ao lado da outra. Assim, descobrimos que todos os
pacientes que evoluíram a óbito foram internados em caráter de
urgência.
Muitos outros gráficos você pode gerar com o ggplot
e
você pode conhecer os comandos neste
link.
E se pudéssemos com algumas poucas linhas de código gerar um gráfico
ao mesmo tempo que gerar a análise estatística deste gráfico e plotar
tudo isso junto? É o que o pacote ggstatsplot
faz por nós.
Pacientes que evoluíram de óbito permaneceram por tempo de internação
maior que pacientes que evoluíram de alta? Vejamos:
dados |>
ggbetweenstats(y = TEMPO,
x = EVOLUCAO,
bf.message = FALSE,
ylab = "Tempo médio de internação (dias)",
xlab = "Evolução do paciente")
O que os dados disseram? Que entre homens de 20 anos ou mais hospitalizados por infarto agudo do miocárdio em Mato Grosso em janeiro de 2023 os pacientes que evoluíram a óbito apresentaram tempo médio de internação estatisticamente menor que os pacientes que evoluíram de alta.
Outra pergunta: O tempo de internação aumenta o custo da internação?
dados |>
ggscatterstats(y = VALOR,
x = TEMPO,
bf.message = FALSE,
ylab = "Custo da internação (R$)",
xlab = "Tempo de internação (dias)")
Sim, houve uma correlação positiva, moderada e estatisticamente significativa entre tempo e custo da internação, ou seja, quanto maior o tempo, maior foi o custo da internação.
Se ao invés de trabalharmos apenas com o mês de janeiro de 2023,
quisermos trabalhar com dados de todos os meses disponíveis deste ano
podemos realizar o procedimento anterior de download dos dados
manualmente um a um ou utilizar o pacote microdatasus
para
automatizar tudo isso. Infelizmente, ele não se encontra no repositório
oficial de pacotes do R, então temos que seguir alguns passos diferentes
para realizar sua instalação:
Agora, utilizaremos o pacote para baixar dados do DATASUS, processar estes dados, aplicar filtros por critérios de inclusão e, por fim, selecionar as variáveis de interesse para o estudo.
#--------- Carregando
library(microdatasus)
#--------- Download
dados <- fetch_datasus(information_system = "SIH-RD",
year_start = 2023,
month_start = 1,
year_end = 2023,
month_end = 12,
uf = "MT",
vars = c("MES_CMPT", "CAR_INT", "DIAS_PERM",
"VAL_TOT", "MORTE", "IDADE",
"COD_IDADE", "DIAG_PRINC", "SEXO"))
#--------- Processamento
dados <- dados |>
filter(COD_IDADE == "4",
IDADE >= 20,
SEXO == "1",
DIAG_PRINC == "I219") |>
select(MES_CMPT, CAR_INT, DIAS_PERM, VAL_TOT, MORTE) |>
mutate(CAR_INT = case_when(CAR_INT == "01" ~ "Eletivo",
CAR_INT == "02" ~ "Urgência"),
MORTE = case_when(MORTE == 0 ~ "Alta",
MORTE == 1 ~ "Óbito")) |>
rename("EVOLUCAO" = "MORTE",
"MES" = "MES_CMPT",
"TEMPO" = "DIAS_PERM",
"VALOR" = "VAL_TOT",
"CARATER" = "CAR_INT")
Teremos então o seguinte dataframe e, com os critérios utilizados, localizamos a ocorrência de 800 internações por infarto agudo do miocárdio entre janeiro e setembro de 2023 em indivíduos do sexo masculino com idade de 20 anos ou mais atendidos pela rede SUS em Mato Grosso.
MES | CARATER | TEMPO | VALOR | EVOLUCAO | |
---|---|---|---|---|---|
530 | 01 | Urgência | 12 | 4885.56 | Alta |
938 | 01 | Urgência | 0 | 1194.47 | Óbito |
1239 | 01 | Urgência | 2 | 589.12 | Alta |
1294 | 01 | Urgência | 3 | 1883.32 | Alta |
1703…5 | 01 | Urgência | 30 | 906.07 | Alta |
1888 | 01 | Urgência | 5 | 588.12 | Alta |
3522 | 01 | Urgência | 2 | 588.12 | Alta |
3821 | 01 | Urgência | 9 | 3240.75 | Alta |
4006 | 01 | Urgência | 1 | 1788.12 | Óbito |
4007 | 01 | Urgência | 17 | 668.36 | Alta |
Podemos agora, com um poder estatístico um pouco melhor, avaliar a proporção da letalidade hospitalar:
dados |>
ggbarstats(y = MES,
x = EVOLUCAO,
bf.message = FALSE,
ylab = "Proporção",
xlab = "Mês de internação",
legend.title = "Evolução",
title = "Letalidade mensal por infarto agudo do miocárdio",
package = "wesanderson",
palette = "Darjeeling1")
Não houve diferença estatisticamente significativa entre os meses de janeiro e setembro de 2023 na letalidade do infarto agudo do miocárdio entre homens de 20 anos ou mais atendidos pela rede SUS em Mato Grosso.
Chegou a hora de você colocar em prática e consolidar as habilidades adquiridas com este curso. Abra um novo script no seu RStudio, salve-o com o nome Desafio Aceito, copie o código abaixo nele e execute:
Você fez o download de dados de declarações de óbitos do Sistema de Informação Sobre Mortalidade (SIM) do DATASUS. Agora vem a missão (que você já aceitou, até escreveu no script rs):
1. Filtrar a causa básica (CAUSABAS) pelo CID-10 de morte instantânea (R960). 2. Selecionar as variáveis da tabela abaixo.
Variáveis | Descrição |
---|---|
DTOBITO | Data do óbito |
DTNASC | Data de nascimento |
SEXO | Sexo |
ESTCIV | Estado civil |
LOCOCOR | Local de ocorrência |
3. Rotular os dados das variáveis SEXO, ESTCIV e LOCOCOR
utilizando case_when
.
SEXO | Rótulo |
---|---|
1 | Masculino |
2 | Feminino |
ESTCIV | Rótulo |
---|---|
1 | Solteiro |
2 | Casado |
3 | Viúvo |
4 | Divorciado |
5 | União consensual |
9 | Não informado |
LOCOCOR | Rótulo |
---|---|
1 | Hospital |
2 | Outro estab. de saúde |
3 | Domicílio |
4 | Via pública |
5 | Outros |
9 | Não informado |
4. Elaborar uma tabela com o pacote gtsummary
com estas três variáveis.
5. Elaborar um gráfico com o pacote ggstatsplot
da sua escolha.
Perguntas a serem respondidas com os dados: