[PT] Fluxos de pacientes internados em UTI por SRAG/COVID

Há algumas semanas publiquei aqui uma análise sobre como o avanço da COVID-19 para o interior dos estados brasileiros trazia mais desafios no enfrentamento da pandemia devido à demanda de leitos e equipamentos.

Seguindo sugestão do Diego Ricardo Xavier comecei a testar visualizações semelhantes a partir dos dados do SIVEP-Gripe (Sistema de Informação de Vigilância Epidemiológica da Gripe) disponibilizados pelo Ministério da Saúde, e que tem incorporado também a vigilância e hospitalizações por COVID-19.

A seguir, apresento os resultados de maneira breve junto com o código para quem se interessar. A ideia foi visualizar os fluxos de pacientes entre municípios que precisaram ser internados em UTI por SRAG/COVID-19. O período considerado vai de 01/01/2020 a 15/06/2020. Agradeço ao Diego pelas contribuições ao longo do processo. =)

Coloquei ambos no YouTube para facilitar o controle de velocidade. Este a seguir apresenta somente os fluxos com capitais como destino.

São Paulo se apresenta como grande centro de destino, até mesmo de alguns pacientes de cidades distantes. No período, foram 2.858 pacientes residentes de outros municípios que precisaram ser internados em UTI. Em seguida, aparecem Rio de Janeiro, Recife e Belo Horizonte, cada uma com respectivamente 1.130, 955 e 694 internações de pacientes de fora durante o período. A seguir é possível observar todos os fluxos para São Paulo no período.

O gráfico abaixo apresenta a evolução do total de internações diárias em cada cidade. No dia 27 de maio, São Paulo registrou 57 internações em UTI de pacientes residentes em outras cidades.

Compartilho aqui o código utilizado para visualização dos fluxos e aproveito para agradecer também o trabalho de todos desenvolvedores dos pacotes utilizados, principalmente do mapdeck, geobr e shiny.

library(shiny)
library(shinyjs)
library(sf)
library(mapdeck)
library(data.table)
library(geobr)
library(tidylog)
library(tidyr)

token = "XXXXXXXXXXXXXXXXXXXXXXXX"

estados <- geobr::read_state()
estados <- st_transform(estados, crs="+init=epsg:4326")

# Diretório Municípios Brasileiros: http://basedosdados.org/dataset/diretorio-municipios-brasileiros
cod_municipios <- read.csv("cod_municipios.csv", stringsAsFactors = F)
cod_municipios$id_munic_6 <- as.character(cod_municipios$id_munic_6)
cod_municipios$id_munic_7 <- as.character(cod_municipios$id_munic_7)

# DADOS DO MINISTÉRIO DA SAÚDE
sivep_2020 <- read.csv2("INFLUD-16-06-2020-Revisado.csv")

sivep_2020$CO_MUN_NOT <- as.character(sivep_2020$CO_MUN_NOT)
sivep_2020 <- left_join(sivep_2020,cod_municipios %>% 
                   select(id_munic_6, id_munic_7),by=c("CO_MUN_NOT"="id_munic_6"))
sivep_2020 <- sivep_2020 %>% rename(cod_munic7_un=id_munic_7)

sivep_2020$CO_MUN_RES <-  as.character(sivep_2020$CO_MUN_RES)
sivep_2020 <- left_join(sivep_2020,cod_municipios %>% 
                          select(id_munic_6, id_munic_7),by=c("CO_MUN_RES"="id_munic_6"))
sivep_2020 <- sivep_2020 %>% rename(cod_munic7_res=id_munic_7)

# CARREGA SEDES DOS MUNICIPIOS
sede_municipios <- geobr::read_municipal_seat()
sede_municipios <- st_transform(sede_municipios, crs="+init=epsg:4326")
sede_municipios$code_muni <- as.character(sede_municipios$code_muni)
sede_municipios <- sede_municipios %>%
  select(code_muni,geom)

# EXTRAI COORDENADAS DAS SEDES MUNICIPAIS
coords_sedes <-  do.call(rbind, st_geometry(sede_municipios)) %>% 
  as_tibble() %>% 
  setNames(c("lon","lat"))

coords_sedes <- cbind(as.data.frame(sede_municipios) %>% 
                        select(code_muni), coords_sedes)

# FIXA COORDENADAS
desloca_sivep_2020 <- sivep_2020 %>% 
  select(DT_NOTIFIC,UTI,DT_ENTUTI,CLASSI_FIN,cod_munic7_res,cod_munic7_un) %>%
  filter(cod_munic7_res!=cod_munic7_un)

desloca_sivep_2020 <- left_join(desloca_sivep_2020, coords_sedes, by=c("cod_munic7_res"="code_muni"))
desloca_sivep_2020 <- desloca_sivep_2020 %>% rename("lon_ori"="lon","lat_ori"="lat")

desloca_sivep_2020 <- left_join(desloca_sivep_2020, coords_sedes, by=c("cod_munic7_un"="code_muni"))
desloca_sivep_2020 <- desloca_sivep_2020 %>% rename("lon_dest"="lon","lat_dest"="lat")

desloca_sivep_2020 <- desloca_sivep_2020 %>% 
  mutate(DT_ENTUTI=as.Date(DT_ENTUTI, format="%d/%m/%Y")) %>%
  filter(DT_ENTUTI >= "2020-01-01" & DT_ENTUTI<="2020-06-15") %>%
  group_by(DT_ENTUTI,cod_munic7_res,cod_munic7_un,lon_ori,lat_ori,lon_dest,lat_dest) %>%
  summarise(internacoes=sum(UTI)) %>%
  mutate(stroke=3.5*sqrt(internacoes))

# CORRIGE AS COORDENADAS DE BALNEÁRIO RINCÃO (SC)
desloca_sivep_2020$lon_ori[desloca_sivep_2020$cod_munic7_res=="4220000"] <- -49.070366
desloca_sivep_2020$lat_ori[desloca_sivep_2020$cod_munic7_res=="4220000"] <- -26.914002

ui <- fillPage(
  shinyjs::useShinyjs(),
  tags$style(
    includeCSS("www/bootstrap.css")
  ),
  header=tags$head(tags$style(type='text/css', ".irs-single { font-size: 24pt;}")),
  mapdeckOutput("mymap", width = "100%", height = "100%"),
  absolutePanel(
    id = "controls", class = "panel panel-default", draggable = F, fixed = T, 
    top = "5%", right = 20, left = "auto", bottom = "auto", height = "auto", width = 375,
    h3("FLUXO DE PACIENTES INTERNADOS EM UTI POR SRAG/COVID-19"),
    h4("DATA DE ENTRADA NA UTI:"),
    sliderInput("data",
                "",
                min = as.Date(min(desloca_sivep_2020$DT_ENTUTI)),
                max = as.Date(max(desloca_sivep_2020$DT_ENTUTI)),
                value = c(as.Date("2020-01-01")),
                timeFormat = "%d-%m-%Y",
                width = "100%",
                animate = animationOptions(interval = 450, loop = F)),
                h4("Fonte: SIVEP Gripe / SRAG 2020 - incluindo dados da COVID-19 (opendatasus.saude.gov.br)"),
                h4("Elaboração: Gabriel Vaz de Melo")
  )
)

server <- function(input, output, session){
  
  output$mymap <- renderMapdeck({
    mapdeck(token = token, 
            style = mapdeck_style("light"), 
            pitch = 30) %>%
      add_sf(
        data = estados
        , layer_id = "limites_estados"
        , fill_opacity = 0
        , stroke_colour = "#00000025"
        , stroke_width = 5000
      ) 
  })
  
  df_reativo <- reactive({
    desloca_sivep_2020 <- data.table(desloca_sivep_2020)[DT_ENTUTI==input$data]
  })
  
  observe({
    
    mapdeck_update(map_id = 'mymap') %>%
      add_animated_arc(
        data = df_reativo()
        , origin = c("lon_ori", "lat_ori")
        , destination = c("lon_dest", "lat_dest")
        , stroke_from = "internacoes"
        , stroke_to = "internacoes"
        , stroke_width = "stroke"
        , animation_speed = 50
        , palette = "plasma"
        , legend = list(stroke_from=T,stroke_to=F)
        , legend_options = list(
          stroke_from=list(title="QUANTIDADE DE INTERNAÇÕES:")
          , css = "max-width: 300px;
                   background-color: #272b30;
                   opacity: 0.95;"
        )
        , legend_format = list(stroke_from = as.integer)
        , update_view = FALSE
      )
    
  })
  
}

shinyApp(ui, server)

Load Comments?