2. Cálculo de frequências

Considere que o profissional de vigilância necessita produzir um relatório analisando as notificações de casos suspeitos ou confirmados de dengue e hepatites virais. Para esta análise você escolheu utilizar o Sistema de Informação em Saúde Sinan Net.

Para construir o relatório, você precisará conhecer o número de casos e para isso irá criar uma tabela de frequência, ou seja, contar quantas vezes um caso foi notificado no banco de dados {NINDINET.dbf}, disponível no menu lateral “Arquivos”, do módulo.


2.1 Frequência absoluta

Agora vamos calcular a frequência absoluta dos valores de colunas específicas na tabela dados. Lembre-se que a base {NINDINET.dbf} foi utilizada para gerar o objeto {dados} .

Para esta avaliação, utilizaremos as funções do pacote dplyr. Os três passos a seguir serão necessários para a construção da tabela de frequência:


  1. Primeiro passo, selecionaremos (filtre) os registros de pacientes por agravos de interesse. Os códigos registrados na tabela do {NINDINET.dbf} para filtrar o agravo dengue e hepatite viral não especificada são respectivamente A90 e B19, de acordo com o CID-10. Estas informações estão contidas na coluna ID_AGRAVO. Você irá escrever assim: filter(ID_AGRAVO %in% c("A90","B19")) |>;

  2. Segundo passo, será necessário organizar os casos encontrados, agrupando de acordo com cada categoria, ou seja, os dois agravos, utilizando a função group_by(). Assim: group_by(ID_AGRAVO) |>;

  3. Terceiro passo, utilize a função summarise() para que o R retorne as informações de interesse para cada valor por agravo. Essa função necessita de dois argumentos para ser executada:

    • o nome da nova coluna contendo as informações que queremos calcular;
    • o comando indicando qual informação de cada grupo queremos obter.

Logo, neste exemplo, vamos criar uma coluna com o nome total, embora qualquer outro nome possa ser escolhido, e vamos contar o número de elementos em cada categoria. Para isso, vamos utilizar a função n(). Assim, nosso comando para esse passo será: summarise(total = n()).

Veja como fica o script com todos os comandos descritos acima:

dados |>
  
  # filtrando os agravos de dengue (código "A90") e hepatite viral (código "B19")
  # com a função filter()
  filter(ID_AGRAVO %in% c("A90", "B19")) |>
  
  # agrupando os agravos (coluna ID_AGRAVO) com a função group_by()
  group_by(ID_AGRAVO) |>
  
  # calculando a frequência de casos com as funcões summarise() e n()
  summarise(total = n())
#> # A tibble: 2 × 2
#>   ID_AGRAVO total
#>   <fct>     <int>
#> 1 A90       12781
#> 2 B19         955

Observe o output do código executado, você deverá encontrar os seguintes valores: 12.781 registros de pacientes notificados com dengue (A90), e 955 pacientes notificados de hepatites virais (B19). Caso você encontre algo diferente, retorne ao código e verifique se todos os comandos estão iguais ao exemplo acima, inclusive vírgulas e parênteses.

Agora, vamos estudar e verificar se existiu diferença entre sexo para notificação dos casos de dengue e hepatites virais. Para isto, calcularemos a frequência absoluta das notificações por sexo no {NINDINET.dbf}. Lembre-se que usaremos a mesma lógica de construção dos códigos utilizados acima. Observe e siga o script abaixo:

dados |>
  
  # agrupando com a função group_by() os indivíduos por sexo (coluna CS_SEXO)
  group_by(CS_SEXO) |>
  
  # calculando a frequência de casos com as funcões summarise() e n()
  summarise(total = n())
#> # A tibble: 3 × 2
#>   CS_SEXO total
#>   <fct>   <int>
#> 1 F       13567
#> 2 I          56
#> 3 M       13998

Perceba que é possível visualizar três valores para a variável sexo (CS_SEXO): F para feminino com 13.567 registros; M para masculino com 13.998 registros e; I para ignorado com apenas 56 registros. No dia a dia na vigilância é comum encontrarmos registros de pacientes em que a informação sobre o sexo está ausente. Agora, podemos ter a seguinte dúvida:


Será que estes registros ignorados ou nulos são mais frequentes no agravo dengue (A90) do que quando analisamos o agravo hepatite(B19)?


Como profissional de vigilância em saúde, para responder à pergunta acima, necessitaremos aprofundar nossa análise, sendo necessário cruzar informações sobre duas variáveis epidemiológicas: identificação do agravo e o sexo do paciente. Dessa forma, deve-se incluir em seu relatório a distribuição das notificações dos agravos por sexo. Para isto, permaneceremos utilizando a função de agrupamento group_by(), para que calcule a frequência para cada grupo de categorias. Siga o script abaixo:

dados |>
  
  #filtrando os agravos de dengue (código "A90") e hepatite viral (código "B19")
  # com a função filter()
  filter(ID_AGRAVO %in% c("A90", "B19")) |>
  
  # agrupando com a função group_by() os agravos (coluna ID_AGRAVO) e indivíduos
  # por sexo (coluna CS_SEXO)
  group_by(ID_AGRAVO, CS_SEXO) |>
  
  # calculando a frequência de casos com as funcões summarise() e n()
  summarise(total = n())
#> # A tibble: 5 × 3
#> # Groups:   ID_AGRAVO [2]
#>   ID_AGRAVO CS_SEXO total
#>   <fct>     <fct>   <int>
#> 1 A90       F        6827
#> 2 A90       I          11
#> 3 A90       M        5943
#> 4 B19       F         418
#> 5 B19       M         537

Perceba que no output do script executado, conforme exemplo acima, as linhas foram ordenadas em ordem alfabética: primeiro para a coluna ID_AGRAVO (A90 e B19), e em seguida para a coluna CS_SEXO (F, I e M).

Podemos ordenar as linhas da tabela de acordo com o que desejarmos. Então, vamos lá ordenar. Para praticar, você irá ordenar as linhas de acordo com o número de registros (coluna total). Para este ordenamento utilizamos as funções arrange(), que ordena a coluna, e desc(), para indicar que a ordem será do maior valor para o menor. Veja:

dados |>
  
  #filtrando os agravos de dengue (código "A90") e hepatite viral (código "B19")
  filter(ID_AGRAVO %in% c("A90", "B19")) |>
  
  # agrupando com a função group_by() os agravos (coluna ID_AGRAVO) e indivíduos 
  # por sexo (coluna CS_SEXO)
  group_by(ID_AGRAVO, CS_SEXO) |>
  
  # calculando a frequência de casos com as funcões summarise() e n()
  summarise(total = n()) |>
  
  # ordenando a frequência de casos (coluna total) em ordem descrescente com a 
  # função arrange()
  arrange(desc(total))
#> # A tibble: 5 × 3
#> # Groups:   ID_AGRAVO [2]
#>   ID_AGRAVO CS_SEXO total
#>   <fct>     <fct>   <int>
#> 1 A90       F        6827
#> 2 A90       M        5943
#> 3 B19       M         537
#> 4 B19       F         418
#> 5 A90       I          11

No retorno acima, os campos com sexo I de ignorado estão todos concentrados no agravo A90. Isso demonstra que a variável CS_SEXO no agravo B19 tem o preenchimento melhor.

Algo que pode ser valioso em algumas análises com R é pedir que ele retorne os valores que estão em branco nas colunas. Assim, você conseguirá saber todos os possíveis valores da sua coluna. Para este ordenamento, o pacote dplyr possui uma função auxiliar que agrupa os dados por uma categoria, e calcula a frequência de cada um simultaneamente. Esta função é count(). Agora vamos praticar:


  1. Primeiro, utilize a função filter() para filtrar a tabela apenas os agravos de interesse;

  2. Segundo, inclua a função mutate() e, dentro dela, a função drop.levels(). Isso fará que o R remova categorias (os chamados levels) que não atendem ao filtro;

  3. Por fim, inclua a função count(), que necessitará receber o argumento drop = FALSE para contabilizar as categorias com frequência igual a zero (0).

Veja abaixo como ficaria a nova distribuição no script seguindo o passo-a-passo com os comandos descritos:

dados |>
  
  # filtrando os agravos de dengue (código "A90") e hepatite viral (código "B19")
  filter(ID_AGRAVO %in% c("A90", "B19")) |>
  
  # utilizando a função mutate() para modificar a coluna ID_AGRAVO, removendo as 
  # categorias (levels) em branco após o filtro usando a função droplevels()
  mutate(ID_AGRAVO = droplevels(ID_AGRAVO)) |>
  
  # contando o total de casos por agravo (coluna ID_AGRAVO) e sexo (coluna CS_SEXO)
  # combinações de categorias com contagem 0 permanecem na tabela pelo uso do 
  # argumento .drop = FALSE
  count(ID_AGRAVO, CS_SEXO, .drop = FALSE)
#>   ID_AGRAVO CS_SEXO    n
#> 1       A90       F 6827
#> 2       A90       I   11
#> 3       A90       M 5943
#> 4       B19       F  418
#> 5       B19       I    0
#> 6       B19       M  537

Observe que a nova tabela uma nova linha com a combinação CS_SEXO = I, referente ao agravo (ID_AGRAVO = B19), sendo o total de I igual a zero (0). Você deve ter percebido que utilizamos uma linha com a função droplevels(). Mas por que ela é necessária?

Mesmo utilizando a função filter() para filtrar apenas os agravos de interesse da tabela {dados}, a coluna ID_AGRAVO é uma variável do tipo factor, ou seja, a coluna retém a informação de todas as categorias (levels) existentes antes da filtragem. Para corrigir esta detalhe e garantir que só serão retornados os agravos A90 e B19, precisamos então utilizar a função drop.levels() dentro da função mutate(). Assim o comando utilizado foi: mutate(ID_AGRAVO = droplevels(ID_AGRAVO)).



Em alguns momentos da rotina da análise da vigilância em saúde poderá ser necessário ordenar categorias de uma forma diferente da ordem alfabética. Para isto, devemos transformar a coluna que queremos ordenar em um fator ordenado.

Lembre-se que no R fatores são um conjunto de categorias, e os valores que essas variáveis assumem são os níveis (levels), ou simplesmente as categorias que compõem o fator. Os fatores são necessários sempre que precisamos representar variáveis categóricas (como as de sexo: F, I, e M, ou raça/cor: Branco, Preto, Amarelo, Pardo e Indígena). Assim podem ser ordenados como desejamos.

Observe abaixo como seria construir um script para visualizar os dados de casos notificados por sexo na seguinte ordem: Feminino (F), Masculino (M), e Ignorado (I). Para esta ordenação utilizaremos a função factor e para especificar a ordem desejada utilizaremos o argumento levels, e por fim adicionaremos o argumento ordered = TRUE, para dizer que queremos ordená-los conforme os levels. Veja as linhas de script com os códigos necessários:

dados |>
  
  # filtrando os agravos de dengue (código "A90") 
  # e hepatite viral (código "B19")
  filter(ID_AGRAVO %in% c("A90", "B19")) |>
  
  # utilizando a função mutate() para transformar a 
  # coluna CS_SEXO
  # em uma variável do tipo "factor", com três 
  # categorias ordenadas
  mutate(CS_SEXO = factor(CS_SEXO, 
  levels = c("F", "M", "I"), ordered = TRUE)) |>
  
  # agrupando com a função group_by() os agravos 
  # (coluna ID_AGRAVO) e 
  # indivíduos por sexo (coluna CS_SEXO)
  group_by(ID_AGRAVO, CS_SEXO) |>
  
  # calculando a frequência de casos com as funcões 
  # summarise() e n()
  summarise(total = n())
#> # A tibble: 5 × 3
#> # Groups:   ID_AGRAVO [2]
#>   ID_AGRAVO CS_SEXO total
#>   <fct>     <ord>   <int>
#> 1 A90       F        6827
#> 2 A90       M        5943
#> 3 A90       I          11
#> 4 B19       F         418
#> 5 B19       M         537

Pronto, ordenamos nosso cálculo de frequência absoluta da coluna CS_SEXO tanto para o agravo A90quanto para o B19, e conseguimos ordenar o sexo também em ordem alfabética. Assim: F, M e I.

2.2 Frequência relativa ou porcentagem

Agora que sabemos como calcular a frequência absoluta dos valores de colunas específicas na tabela {dados}, um segundo passo a ser feito é calcular também a proporção de cada um desses agravos em nosso conjunto de dados.

Para saber esta proporção, vamos realizar um cálculo de divisão: dividindo a frequência absoluta de cada categoria (agravo) pela frequência absoluta total dos valores (soma de todas os notificados por dengue e hepatites não especificadas).

Abaixo, observe o script que possui os códigos de comando e perceba que adicionamos uma linha com a função mutate() para que seja possível dividir cada valor da coluna total pela soma geral da coluna (sum(total)). Veja abaixo os comandos e os resultados:

dados |>
  
  # filtrando os agravos de dengue (código "A90") e hepatite viral (código "B19")
  filter(ID_AGRAVO %in% c("A90", "B19")) |>
  
  # agrupando com a função group_by() os agravos (coluna ID_AGRAVO)
  group_by(ID_AGRAVO) |>
  
  # calculando a frequência de casos com as funcões summarise() e n()
  summarise(total = n()) |>
  
  # calculando a proporção de casos ao dividir o total pela soma de valores
  # total pelo uso das funções mutate() e sum()
  mutate(proporcao = total / sum(total))
#> # A tibble: 2 × 3
#>   ID_AGRAVO total proporcao
#>   <fct>     <int>     <dbl>
#> 1 A90       12781    0.930 
#> 2 B19         955    0.0695

Ao executarmos esta operação, obtemos uma tabela que contém a coluna “proporcao” com valores decimais entre 0 e 1 onde A90 possui 0,93 dos registros e B19 possui apenas 0,0695. Para facilitar a nossa visualização, convertemos esse valor para um valor do tipo porcentagem (0% a 100%), da seguinte forma:

  1. Primeiro, realizamos os mesmos cálculos do exemplo anterior;
  2. Segundo, multiplicamos o valor resultante da coluna proporcao por 100;
  3. Terceiro, arredondamos o resultado em duas casas decimais utilizando a função round() e o seu argumento digits = 2.

Observe o script abaixo:

dados |>
  
  # filtrando os agravos de dengue (código "A90") e hepatite viral (código "B19")
  # com a função filter()
  filter(ID_AGRAVO %in% c("A90", "B19")) |>
  
  # agrupando com a função group_by() os agravos (coluna ID_AGRAVO)
  group_by(ID_AGRAVO) |>
  
  # calculando a frequência de casos com as funcões summarise() e n()
  summarise(total = n()) |>
  
  # calculando a proporção de casos ao dividir o total pela soma de valores total
  # pelo uso das funções mutate() e sum()
  mutate(proporcao = total / sum(total)) |>
  
  # criando uma nova coluna (porcentagem) com o uso da função mutate()
  # utilizando a função round() para arredondar em duas casas decimais a
  # porcentagem, após multiplicar a coluna "proporcao" por 100
  mutate(porcentagem = round(proporcao * 100, digits = 2))
#> # A tibble: 2 × 4
#>   ID_AGRAVO total proporcao porcentagem
#>   <fct>     <int>     <dbl>       <dbl>
#> 1 A90       12781    0.930        93.0 
#> 2 B19         955    0.0695        6.95

Pronto, agora temos uma tabela para ser adicionada à análise de situação da saúde de Rosas, com a frequência relativa dos dados entre os agravos A90 e B19, ou seja, a dengue (A90) possui 93% (proporção = 0,93) dos registros e as hepatites virais (B19) 6,95% (proporção = 0,0695).

Tente reproduzir esta etapa com o {NINDINET.dbf} de seu município ou estado e visualize as frequências absolutas e relativas avaliando quais os agravos de maior magnitude.