Consolidações: Mato Grosso do Sul
Informações Gerais
> Lembre-se de ativar o runtime para Mix Standalone
com o caminho para /data
Objetivo deste book consiste em gerar consolidações dos seguintes indicadores do linkage do estado de Mato Grosso do Sul.
Dimensões
Por situação de vacinação
-
n/a
- Desconsiderando a vacinação -
no_vaccine
- Considerando apenas quem não foi vacinado -
partial_vaccine
- Considerando apenas quem foi vacinado uma vez para vacinas de 2 doses -
full_vaccine
- Considerando apenas quem foi vacinado com a quantidade esperada de doses da vacina -
guarded
- Considerandofull_vaccine
com, ao menos, 14 dias depois da data dos primeiros sintomas
Faixas etárias
-
18-29
- Considerando na idade entre 18 e 29 anos -
30-39
- Considerando na idade entre 30 e 39 anos -
40-49
- Considerando na idade entre 40 e 49 anos -
50-59
- Considerando na idade entre 50 e 59 anos -
60-69
- Considerando na idade entre 60 e 69 anos -
70-79
- Considerando na idade entre 70 e 79 anos -
80+
- Considerando na idade de 80 anos ou maior
Consolidações e-SUS VE
-
esus_ve_cases
- Casos sintomáticos do e-SUS VE:-
esus_ve_cases
(faixas etárias, situação de vacinaçãon/a
) -
esus_ve_cases_no_vaccine
(faixas etárias) -
esus_ve_cases_partial_vaccine
(faixas etárias) -
esus_ve_cases_full_vaccine
(faixas etárias) -
esus_ve_cases_guarded
(faixas etárias)
-
Consolidações SIPNI
-
sipni
- Vacinações (SIPNI):-
sipni_partial_vaccine
(faixas etárias) -
sipni_full_vaccine
(faixas etárias)
-
Consolidações SIVEP
-
sivep_cases
- Casos do SIVEP:-
sivep_cases
(faixas etárias, situação de vacinaçãon/a
) -
sivep_cases_no_vaccine
(faixas etárias) -
sivep_cases_partial_vaccine
(faixas etárias) -
sivep_cases_full_vaccine
(faixas etárias) -
sivep_cases_guarded
(faixas etárias)
-
-
sivep_hospitalizations
- Internações (SIVEP):-
sivep_hospitalizations
(faixas etárias, situação de vacinaçãon/a
) -
sivep_hospitalizations_no_vaccine
(faixas etárias) -
sivep_hospitalizations_partial_vaccine
(faixas etárias) -
sivep_hospitalizations_full_vaccine
(faixas etárias) -
sivep_hospitalizations_guarded
(faixas etárias)
-
-
sivep_deaths
- Óbitos (SIVEP):-
sivep_deaths
(faixas etárias, situação de vacinaçãon/a
) -
sivep_deaths_no_vaccine
(faixas etárias) -
sivep_deaths_partial_vaccine
(faixas etárias) -
sivep_deaths_full_vaccine
(faixas etárias) -
sivep_deaths_guarded
(faixas etárias)
-
Entrada
Saída
Identificação dos caminhos
get_input_path = fn context ->
"Caminho para #{context}: "
|> IO.gets()
|> String.trim()
|> Path.expand(__DIR__)
|> tap(&unless(File.exists?(&1), do: raise("Caminho #{&1} não existe.")))
end
get_destination_path = fn context ->
"Caminho para #{context}: "
|> IO.gets()
|> String.trim()
|> Path.expand(__DIR__)
|> tap(&File.mkdir_p!(&1))
end
paths = %{
input: %{
linkage: get_input_path.("o linkage")
},
output: get_destination_path.("o diretório de resultados")
}
Definição de funções e variáveis
create_ets = fn ets_table ->
try do
:ets.new(ets_table, [:set, :public, :named_table])
rescue
_error -> :ets.delete_all_objects(ets_table)
end
end
create_ets.(:cities)
city_name = &:ets.lookup_element(:cities, &1, 2)
"sandbox/input/ms_cities_names.csv"
|> Path.expand(__DIR__)
|> File.read!()
|> NimbleCSV.RFC4180.parse_string()
|> Enum.map(fn [k, v] -> {String.to_integer(k), v} end)
|> then(&[{50, "Mato Grosso do Sul"} | &1])
|> then(&:ets.insert(:cities, &1))
add_state = fn ets_table, state, date, age_index, default ->
:ets.update_counter(ets_table, {state, date}, {age_index + 1, 1}, default)
end
add_both = fn ets_table, state, city, date, age_index, default_state, default_city ->
:ets.update_counter(ets_table, {state, date}, {age_index + 1, 1}, default_state)
:ets.update_counter(ets_table, {city, date}, {age_index + 1, 1}, default_city)
end
header = ~w(location date age_15_29 age_30_39 age_40_49 age_50_59 age_60_69 age_70_79 age_80_plus)
wrap = fn ets_table ->
fn _input_path, output_path ->
ets_table
|> :ets.tab2list()
|> Enum.map(fn values ->
[{city, date} | values] = Tuple.to_list(values)
[city, date | values]
end)
|> Enum.sort(&(Enum.at(&1, 1) <= Enum.at(&2, 1)))
|> Enum.sort(&(List.first(&1) <= List.first(&2)))
|> then(&[header | &1])
|> NimbleCSV.RFC4180.dump_to_iodata()
|> then(&File.write(output_path, &1))
end
end
keys = ~w(15_29 30_39 40_49 50_59 60_69 70_79 80+)
show_plot = fn context, city, data ->
[title: city_name.(city), width: 150, height: 150]
|> VegaLite.new()
|> VegaLite.data_from_values(data)
|> VegaLite.mark(:line)
|> VegaLite.transform(fold: keys)
|> VegaLite.encode_field(:x, "data", type: :temporal)
|> VegaLite.encode_field(:y, "value", type: :quantitative, title: context)
|> VegaLite.encode_field(:color, "key", type: :nominal, title: "Faixa etária")
end
show_plots = fn title, context, path ->
[title: title]
|> VegaLite.new()
|> VegaLite.concat(
path
|> File.read!()
|> NimbleCSV.RFC4180.parse_string()
|> Enum.map(fn [city, date | data] ->
keys
|> Enum.zip(Enum.map(data, &String.to_integer/1))
|> then(&[{"localidade", String.to_integer(city)}, {"data", date} | &1])
|> Enum.into(%{})
end)
|> Enum.group_by(& &1["localidade"])
|> Enum.sort(fn {k1, _}, {k2, _} -> k1 <= k2 end)
|> Enum.map(fn {city, data} -> show_plot.(context, city, data) end)
)
end
show_ets = fn ets_table ->
ets_table
|> Kino.ETS.new()
|> Kino.render()
end
show_table = fn path ->
path
|> File.read!()
|> NimbleCSV.RFC4180.parse_string()
|> Enum.map(fn [city, date | line] ->
keys
|> Enum.zip(line)
|> Enum.map(fn {k, v} -> {k, String.to_integer(v)} end)
|> then(&[{"localidade", city}, {"data", date} | &1])
end)
|> Kino.DataTable.new()
end
force? = false
:ok
esus_ve_cases
# force? = true
esus_ve =
:esus_ve
|> Phi.Pipe.new(paths.input.linkage)
|> Phi.Pipe.run(
:cases,
fn input_path, output_path ->
create_ets.(:na)
create_ets.(:no_vaccine)
create_ets.(:partial_vaccine)
create_ets.(:full_vaccine)
create_ets.(:guarded)
paths.input.linkage
|> File.stream!(read_ahead: 100_000)
|> NimbleCSV.RFC4180.parse_stream()
|> Flow.from_enumerable()
|> Flow.map(fn [_, city, age_index, date, _, vaccination_date, _, _, _, is_full_vaccination] ->
age_index = String.to_integer(age_index)
default_state = {{50, date}, 0, 0, 0, 0, 0, 0, 0}
add =
if city != "" do
default_city = {{city, date}, 0, 0, 0, 0, 0, 0, 0}
&add_both.(
&1,
50,
String.to_integer(city),
date,
age_index,
default_state,
default_city
)
else
&add_state.(&1, 50, date, age_index, default_state)
end
if date != "" do
add.(:na)
if is_full_vaccination == "1" do
add.(:full_vaccine)
date
|> Date.from_iso8601!()
|> Date.diff(Date.from_iso8601!(vaccination_date))
|> then(&(&1 > 14))
|> if(do: add.(:guarded))
else
if is_full_vaccination == "0" do
add.(:partial_vaccine)
else
add.(:no_vaccine)
end
end
end
end)
|> Flow.run()
wrap.(:na).(input_path, output_path)
end,
result_dir: paths.output,
force?: force?
)
|> Phi.Pipe.run(:cases_no_vaccine, wrap.(:no_vaccine), force?: force?)
|> Phi.Pipe.run(:cases_partial_vaccine, wrap.(:partial_vaccine), force?: force?)
|> Phi.Pipe.run(:cases_full_vaccine, wrap.(:full_vaccine), force?: force?)
|> Phi.Pipe.run(:cases_guarded, wrap.(:guarded), force?: force?)
show_plots.(
"e-SUS VE: Casos sintomáticos ocorridos após 15 dias da data de vacinação completa",
"Casos",
esus_ve.path
)
sipni
# force? = true
sipni =
:sipni
|> Phi.Pipe.new(paths.input.linkage)
|> Phi.Pipe.run(
:partial_vaccine,
fn input_path, output_path ->
create_ets.(:partial_vaccine)
create_ets.(:full_vaccine)
paths.input.linkage
|> File.stream!(read_ahead: 100_000)
|> NimbleCSV.RFC4180.parse_stream()
|> Flow.from_enumerable()
|> Flow.map(fn [_, city, age_index, _, _, date, _, _, _, is_full_vaccination] ->
age_index = String.to_integer(age_index)
default_state = {{50, date}, 0, 0, 0, 0, 0, 0, 0}
add =
if city != "" do
default_city = {{city, date}, 0, 0, 0, 0, 0, 0, 0}
&add_both.(
&1,
50,
String.to_integer(city),
date,
age_index,
default_state,
default_city
)
else
&add_state.(&1, 50, date, age_index, default_state)
end
if is_full_vaccination == "1" do
add.(:full_vaccine)
else
if is_full_vaccination == "0" do
add.(:partial_vaccine)
end
end
end)
|> Flow.run()
wrap.(:partial_vaccine).(input_path, output_path)
end,
result_dir: paths.output,
force?: force?
)
|> Phi.Pipe.run(:full_vaccine, wrap.(:full_vaccine), force?: force?)
show_plots.(
"SIPNI: Vacinações completas (1 com a Janssen ou 2 de outro laboratório)",
"Vacinações",
sipni.path
)
sivep_cases
# force? = true
sivep =
:sivep
|> Phi.Pipe.new(paths.input.linkage)
|> Phi.Pipe.run(
:cases,
fn input_path, output_path ->
create_ets.(:na)
create_ets.(:no_vaccine)
create_ets.(:partial_vaccine)
create_ets.(:full_vaccine)
create_ets.(:guarded)
paths.input.linkage
|> File.stream!(read_ahead: 100_000)
|> NimbleCSV.RFC4180.parse_stream()
|> Flow.from_enumerable()
|> Flow.map(fn [
_,
city,
age_index,
_,
date,
vaccination_date,
is_case,
_,
_,
is_full_vaccination
] ->
age_index = String.to_integer(age_index)
default_state = {{50, date}, 0, 0, 0, 0, 0, 0, 0}
add =
if city != "" do
default_city = {{city, date}, 0, 0, 0, 0, 0, 0, 0}
&add_both.(
&1,
50,
String.to_integer(city),
date,
age_index,
default_state,
default_city
)
else
&add_state.(&1, 50, date, age_index, default_state)
end
if date != "" and is_case == "1" do
add.(:na)
if is_full_vaccination == "1" do
add.(:full_vaccine)
date
|> Date.from_iso8601!()
|> Date.diff(Date.from_iso8601!(vaccination_date))
|> then(&(&1 > 14))
|> if(do: add.(:guarded))
else
if is_full_vaccination == "0" do
add.(:partial_vaccine)
else
add.(:no_vaccine)
end
end
end
end)
|> Flow.run()
wrap.(:na).(input_path, output_path)
end,
result_dir: paths.output,
force?: force?
)
|> Phi.Pipe.run(:cases_no_vaccine, wrap.(:no_vaccine), force?: force?)
|> Phi.Pipe.run(:cases_partial_vaccine, wrap.(:partial_vaccine), force?: force?)
|> Phi.Pipe.run(:cases_full_vaccine, wrap.(:full_vaccine), force?: force?)
|> Phi.Pipe.run(:cases_guarded, wrap.(:guarded), force?: force?)
show_plots.(
"SIVEP: Casos ocorridos após 15 dias da data de vacinação completa",
"Casos",
sivep.path
)
sivep_hospitalizations
# force? = true
sivep =
sivep
|> Phi.Pipe.run(
:hospitalizations,
fn input_path, output_path ->
create_ets.(:na)
create_ets.(:no_vaccine)
create_ets.(:partial_vaccine)
create_ets.(:full_vaccine)
create_ets.(:guarded)
paths.input.linkage
|> File.stream!(read_ahead: 100_000)
|> NimbleCSV.RFC4180.parse_stream()
|> Flow.from_enumerable()
|> Flow.map(fn [
_,
city,
age_index,
_,
date,
vaccination_date,
_,
is_hospitalization,
_,
is_full_vaccination
] ->
age_index = String.to_integer(age_index)
default_state = {{50, date}, 0, 0, 0, 0, 0, 0, 0}
add =
if city != "" do
default_city = {{city, date}, 0, 0, 0, 0, 0, 0, 0}
&add_both.(
&1,
50,
String.to_integer(city),
date,
age_index,
default_state,
default_city
)
else
&add_state.(&1, 50, date, age_index, default_state)
end
if date != "" and is_hospitalization == "1" do
add.(:na)
if is_full_vaccination == "1" do
add.(:full_vaccine)
date
|> Date.from_iso8601!()
|> Date.diff(Date.from_iso8601!(vaccination_date))
|> then(&(&1 > 14))
|> if(do: add.(:guarded))
else
if is_full_vaccination == "0" do
add.(:partial_vaccine)
else
add.(:no_vaccine)
end
end
end
end)
|> Flow.run()
wrap.(:na).(input_path, output_path)
end,
force?: force?
)
|> Phi.Pipe.run(:hospitalizations_no_vaccine, wrap.(:no_vaccine), force?: force?)
|> Phi.Pipe.run(:hospitalizations_partial_vaccine, wrap.(:partial_vaccine), force?: force?)
|> Phi.Pipe.run(:hospitalizations_full_vaccine, wrap.(:full_vaccine), force?: force?)
|> Phi.Pipe.run(:hospitalizations_guarded, wrap.(:guarded), force?: force?)
show_plots.(
"SIVEP: Internações ocorridas após 15 dias da data de vacinação completa",
"Casos",
sivep.path
)
sivep_deaths
# force? = true
sivep =
sivep
|> Phi.Pipe.run(
:deaths,
fn input_path, output_path ->
create_ets.(:na)
create_ets.(:no_vaccine)
create_ets.(:partial_vaccine)
create_ets.(:full_vaccine)
create_ets.(:guarded)
paths.input.linkage
|> File.stream!(read_ahead: 100_000)
|> NimbleCSV.RFC4180.parse_stream()
|> Flow.from_enumerable()
|> Flow.map(fn [
_,
city,
age_index,
_,
date,
vaccination_date,
_,
_,
is_death,
is_full_vaccination
] ->
age_index = String.to_integer(age_index)
default_state = {{50, date}, 0, 0, 0, 0, 0, 0, 0}
add =
if city != "" do
default_city = {{city, date}, 0, 0, 0, 0, 0, 0, 0}
&add_both.(
&1,
50,
String.to_integer(city),
date,
age_index,
default_state,
default_city
)
else
&add_state.(&1, 50, date, age_index, default_state)
end
if date != "" and is_death == "1" do
add.(:na)
if is_full_vaccination == "1" do
add.(:full_vaccine)
date
|> Date.from_iso8601!()
|> Date.diff(Date.from_iso8601!(vaccination_date))
|> then(&(&1 > 14))
|> if(do: add.(:guarded))
else
if is_full_vaccination == "0" do
add.(:partial_vaccine)
else
add.(:no_vaccine)
end
end
end
end)
|> Flow.run()
wrap.(:na).(input_path, output_path)
end,
result_dir: paths.output,
force?: force?
)
|> Phi.Pipe.run(:deaths_no_vaccine, wrap.(:no_vaccine), force?: force?)
|> Phi.Pipe.run(:deaths_partial_vaccine, wrap.(:partial_vaccine), force?: force?)
|> Phi.Pipe.run(:deaths_full_vaccine, wrap.(:full_vaccine), force?: force?)
|> Phi.Pipe.run(:deaths_guarded, wrap.(:guarded), force?: force?)
show_plots.(
"SIVEP: Óbitos ocorridos após 15 dias da data de vacinação completa",
"Óbitos",
sivep.path
)
Zip
path = "sandbox/results" |> Path.expand(__DIR__)
path
|> File.ls!()
|> Enum.filter(&(String.first(&1) == "0"))
|> Enum.map(&String.to_charlist/1)
|> then(
&:zip.create(
path |> Path.join("processamento.zip") |> String.to_charlist(),
&1,
cwd: String.to_charlist(path)
)
)