Concatenando data.frames
Como juntar os diversos arquivos .dbc do DATASUS em um data.frame; comparação de tempos de processamento e bibliotecas.
Introdução
O DATASUS, braço tecnológico do Ministério da Saúde, disponibiliza uma vasta quantidade de informações sobre diversos aspectos do Serviço Unificado de Saúde (SUS). Muitos destes arquivos são disponibilizados em um formato dbc, que é um “compressed DBF”.
Estes arquivos são disponibilizados no site de FTP do DATASUS. Para fins deste pequeno experimento, todos os arquivos foram baixados e estão na máquina local.
O objetivo deste pequeno estudo é verificar os tempos gastos em cada etapa: leitura dos arquivos, filtros e seleção de variáveis, e a transformação em um data.frame para posterior manipulação.
Carregando as bibliotecas
#| label: bibliotecas
library(tidyverse)
library(read.dbc)
library(data.table)
library(microbenchmark)Listando todos os arquivos das APACS no diretório
Todos os arquivos das APACs foram baixados do site FTP do DATASUS.
#| label: ftpdir
diretorio <- "/datahome/datasets/datasus.gov.br/SIASUS/PA-LaudosDiversos/"Selecionando 4 arquivos, 2 de cada estado, de Minas Gerais e Rio de Janeiro
#| label: mgrj
PREF <- "PA"
# indique o estado ou "" para todos os estados
UF <- "(MG|RJ)"
MESES <- "12"
ANO <- "(18|19)"#| label: mgrjarqs
arquivos <- list.files(diretorio, paste0(PREF,UF,ANO,MESES,".*.dbc"))Variáveis selecionadas
#| label: varstokeep
vars_to_keep = c("PA_CODUNI","PA_UFMUN","PA_TPUPS","PA_TIPPRE", "PA_CNPJCPF", "PA_MVM","PA_CMP","PA_PROC_ID","PA_CNSMED","PA_MOTSAI","PA_OBITO","PA_CIDPRI", "PA_CIDSEC","PA_CIDCAS","PA_CATEND","PA_IDADE","PA_SEXO","PA_RACACOR","PA_MUNPCN", "PA_UFDIF","PA_MNDIF","PA_ETNIA")Tempo de leitura dos arquivos (em segundos)
#| label: readingmgrj
timeMGRJ4arqs <- system.time({f1 <- read.dbc(paste0(diretorio,arquivos[1]));
f2 <- read.dbc(paste0(diretorio,arquivos[2]));
f3 <- read.dbc(paste0(diretorio,arquivos[3]));
f4 <- read.dbc(paste0(diretorio,arquivos[4]));})
timeMGRJ4arqs user system elapsed
82.165 16.305 98.629
Montando uma lista de data.frames
Para estes 4 arquivos iniciais, vou fazer o processo de montar a lista e concatenar usando as duas bibliotecas data.table e dplyr para comparar o tempo nesta etapa.
Cada data.frame inicial é filtrado e as variáveis são selecionadas; são colocados em uma lista de data.frames para a concatenação posterior.
Usando o data.table
#| label: listmgrj
apacsdt <- list()
timeMGRJ4arqs_tolistdt <- system.time({
# f1
f1 <- setDT(f1)
f1 <-
f1[(PA_PROC_ID == "0204030030" |
PA_PROC_ID == "0204030188") &
PA_SEXO == "F", ..vars_to_keep]
estado <- substr(arquivos[1], 3, 4)
ano <- substr(arquivos[1], 5, 6)
mes <- substr(arquivos[1], 7, 8)
ano <- as.numeric(paste0("20", ano))
f1[, `:=`(ESTADO = estado,
ANO = ano,
MES = mes)]
apacsdt <- append(apacsdt, list(f1))
#f2
f2 <- setDT(f2)
f2 <-
f2[(PA_PROC_ID == "0204030030" |
PA_PROC_ID == "0204030188") &
PA_SEXO == "F", ..vars_to_keep]
estado <- substr(arquivos[2], 3, 4)
ano <- substr(arquivos[2], 5, 6)
mes <- substr(arquivos[2], 7, 8)
ano <- as.numeric(paste0("20", ano))
f2[, `:=`(ESTADO = estado,
ANO = ano,
MES = mes)]
apacsdt <- append(apacsdt, list(f2))
# f3
f3 <- setDT(f3)
f3 <-
f3[(PA_PROC_ID == "0204030030" |
PA_PROC_ID == "0204030188") &
PA_SEXO == "F", ..vars_to_keep]
estado <- substr(arquivos[3], 3, 4)
ano <- substr(arquivos[3], 5, 6)
mes <- substr(arquivos[3], 7, 8)
ano <- as.numeric(paste0("20", ano))
f3[, `:=`(ESTADO = estado,
ANO = ano,
MES = mes)]
apacsdt <- append(apacsdt, list(f3))
# f4
f4 <- setDT(f4)
f4 <-
f4[(PA_PROC_ID == "0204030030" |
PA_PROC_ID == "0204030188") &
PA_SEXO == "F", ..vars_to_keep]
estado <- substr(arquivos[4], 3, 4)
ano <- substr(arquivos[4], 5, 6)
mes <- substr(arquivos[4], 7, 8)
ano <- as.numeric(paste0("20", ano))
f4[, `:=`(ESTADO = estado,
ANO = ano,
MES = mes)]
apacsdt <- append(apacsdt, list(f4))
})
timeMGRJ4arqs_tolistdt user system elapsed
0.597 0.000 0.133
Usando o dplyr
#| label: listmgrjdplyr
apacs <- list()
timeMGRJ4arqs_tolistdplyr <- system.time({
# f1
f1 <- f1 %>% filter((PA_PROC_ID == "0204030030" |
PA_PROC_ID == "0204030188") &
PA_SEXO == "F") %>%
select(all_of(vars_to_keep))
estado <- substr(arquivos[1], 3, 4)
ano <- substr(arquivos[1], 5, 6)
mes <- substr(arquivos[1], 7, 8)
ano <- as.numeric(paste0("20", ano))
f1 <- f1 %>% mutate(ESTADO=estado,ANO=ano,MES=mes)
apacs <- append(apacs, list(f1))
#f2
f2 <- f2 %>% filter((PA_PROC_ID == "0204030030" |
PA_PROC_ID == "0204030188") &
PA_SEXO == "F") %>%
select(all_of(vars_to_keep))
estado <- substr(arquivos[2], 3, 4)
ano <- substr(arquivos[2], 5, 6)
mes <- substr(arquivos[2], 7, 8)
ano <- as.numeric(paste0("20", ano))
f2 <- f2 %>% mutate(ESTADO=estado,ANO=ano,MES=mes)
apacs <- append(apacs, list(f2))
# f3
f3 <- f3 %>% filter((PA_PROC_ID == "0204030030" |
PA_PROC_ID == "0204030188") &
PA_SEXO == "F") %>%
select(all_of(vars_to_keep))
estado <- substr(arquivos[3], 3, 4)
ano <- substr(arquivos[3], 5, 6)
mes <- substr(arquivos[3], 7, 8)
ano <- as.numeric(paste0("20", ano))
f3 <- f3 %>% mutate(ESTADO=estado,ANO=ano,MES=mes)
apacs <- append(apacs, list(f3))
# f4
f4 <- f4 %>% filter((PA_PROC_ID == "0204030030" |
PA_PROC_ID == "0204030188") &
PA_SEXO == "F") %>%
select(all_of(vars_to_keep))
estado <- substr(arquivos[4], 3, 4)
ano <- substr(arquivos[4], 5, 6)
mes <- substr(arquivos[4], 7, 8)
ano <- as.numeric(paste0("20", ano))
f4 <- f4 %>% mutate(ESTADO=estado,ANO=ano,MES=mes)
apacs <- append(apacs, list(f4))
})
timeMGRJ4arqs_tolistdplyr user system elapsed
0.099 0.002 0.107
Concatenando os data.frames
Com a função rbindlist do pacote data.table
#| label: dfdtmgrj
timeMGRJ4arqs_todf <- system.time({
X <-
data.table::rbindlist(apacsdt)
assign("APACSPA_MGRJdt", X)
rm(X)
})
timeMGRJ4arqs_todf user system elapsed
0.07 0.000 0.008
Com a função bind_rows do pacote dplyr
#| label: dfdplyrmgrj
timeMGRJ4arqs_tolistdplyr <- system.time({
X <-
bind_rows(apacs)
assign("APACSPA_MGRJdplyr", X)
rm(X)
})
timeMGRJ4arqs_tolistdplyr user system elapsed
0.029 0.000 0.029
Selecionando 4 arquivos de São Paulo
#| label: sp
PREF <- "PA"
# indique o estado ou "" para todos os estados
UF <- "SP"
MESES <- "(01|02)"
ANO <- "19"#| label: sparqs
arquivos <- list.files(diretorio, paste0(PREF,UF,ANO,MESES,".*.dbc"))Tempo de leitura dos arquivos (em segundos)
#| label: readingsp
timeSP4arqs <- system.time({f1 <- read.dbc(paste0(diretorio,arquivos[1]));
f2 <- read.dbc(paste0(diretorio,arquivos[2]));
f3 <- read.dbc(paste0(diretorio,arquivos[3]));
f4 <- read.dbc(paste0(diretorio,arquivos[4]));})
timeSP4arqs user system elapsed
102.826 13.100 116.002
Montando a lista de data.frames
#| label: listsp
apacs <- list()
timeSP4arqs_tolist <- system.time({
# f1
f1 <- setDT(f1)
f1 <-
f1[(PA_PROC_ID == "0204030030" |
PA_PROC_ID == "0204030188") &
PA_SEXO == "F", ..vars_to_keep]
estado <- substr(arquivos[1], 3, 4)
ano <- substr(arquivos[1], 5, 6)
mes <- substr(arquivos[1], 7, 8)
ano <- as.numeric(paste0("20", ano))
f1[, `:=`(ESTADO = estado,
ANO = ano,
MES = mes)]
apacs <- append(apacs, list(f1))
# f2
f2 <- setDT(f2)
f2 <-
f2[(PA_PROC_ID == "0204030030" |
PA_PROC_ID == "0204030188") &
PA_SEXO == "F", ..vars_to_keep]
estado <- substr(arquivos[2], 3, 4)
ano <- substr(arquivos[2], 5, 6)
mes <- substr(arquivos[2], 7, 8)
ano <- as.numeric(paste0("20", ano))
f2[, `:=`(ESTADO = estado,
ANO = ano,
MES = mes)]
apacs <- append(apacs, list(f2))
# f3
f3 <- setDT(f3)
f3 <-
f3[(PA_PROC_ID == "0204030030" |
PA_PROC_ID == "0204030188") &
PA_SEXO == "F", ..vars_to_keep]
estado <- substr(arquivos[3], 3, 4)
ano <- substr(arquivos[3], 5, 6)
mes <- substr(arquivos[3], 7, 8)
ano <- as.numeric(paste0("20", ano))
f3[, `:=`(ESTADO = estado,
ANO = ano,
MES = mes)]
apacs <- append(apacs, list(f3))
# f4
f4 <- setDT(f4)
f4 <-
f4[(PA_PROC_ID == "0204030030" |
PA_PROC_ID == "0204030188") &
PA_SEXO == "F", ..vars_to_keep]
estado <- substr(arquivos[4], 3, 4)
ano <- substr(arquivos[4], 5, 6)
mes <- substr(arquivos[4], 7, 8)
ano <- as.numeric(paste0("20", ano))
f4[, `:=`(ESTADO = estado,
ANO = ano,
MES = mes)]
apacs <- append(apacs, list(f4))
})
timeSP4arqs_tolist user system elapsed
0.841 0.000 0.143
Concatenando os data.frames
Com a função rbindlist do pacote data.table
#| label: dfdtsp
timeSP4arqs_todf <- system.time({
X <-
data.table::rbindlist(apacs)
assign("APACSPA_SPdt", X)
rm(X)
})
timeSP4arqs_todf user system elapsed
0.012 0.000 0.011
Com a função bind_rows do pacote dplyr
#| label: dfdplyrsp
timeSP4arqs_tolistdplyr <- system.time({
X <-
bind_rows(apacs)
assign("APACSPA_SPdplyr", X)
rm(X)
})
timeSP4arqs_tolistdplyr user system elapsed
0.035 0.000 0.035
Gravando um CSV
Usando data.table - função fwrite
#| label: writecsvdt
caminho <- getwd()
nomearquivocsv <- "APACSSPdt.CSV"
system.time(fwrite(APACSPA_SPdt,paste(caminho,nomearquivocsv,sep="/"))) user system elapsed
0.768 0.029 0.108
Usando readr - função write_csv
#| label: writecsvdplyr
nomearquivocsv <- "APACSSPdplyr.CSV"
system.time(write_csv(APACSPA_SPdt,paste(caminho,nomearquivocsv,sep="/"))) user system elapsed
0.432 0.457 0.360