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:
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 respectivamenteA90
eB19
, de acordo com o CID-10. Estas informações estão contidas na colunaID_AGRAVO
. Você irá escrever assim:filter(ID_AGRAVO %in% c("A90","B19")) |>
;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) |>
;Terceiro passo, utilize a função
summarise()
para que oR
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:
Primeiro, utilize a função
filter()
para filtrar a tabela apenas os agravos de interesse;Segundo, inclua a função
mutate()
e, dentro dela, a funçãodrop.levels()
. Isso fará que oR
remova categorias (os chamados levels) que não atendem ao filtro;Por fim, inclua a função
count()
, que necessitará receber o argumentodrop = 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 A90
quanto 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:
- Primeiro, realizamos os mesmos cálculos do exemplo anterior;
- Segundo, multiplicamos o valor resultante da coluna
proporcao
por 100; - Terceiro, arredondamos o resultado em duas casas decimais utilizando
a função
round()
e o seu argumentodigits = 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.