Violência contra a Mulher: dados do Governo Federal, formattable e leaflet

Larissa Sayuri Futino Castro Dos Santos
rladiesbh

--

Violência significa usar a agressividade de forma intencional e excessiva para ameaçar ou cometer algum ato que resulte em acidente, morte ou trauma psicológico.

Nos casos de violência contra a mulher o ato ou prática de violência visa um grupo específico, com o gênero da vítima sendo o motivo principal. Ou seja, os atos de violência são cometidos contra as mulheres expressamente porque são mulheres.

O R-Ladies BH repudia toda e qualquer forma de violência, contra quaisquer indivíduos ou seres vivos.

Também acreditamos que o combate a tais práticas, demanda comunicação constante sobre o assunto:

  • para quebrar esteriótipos quanto ao perfil ou comportamento das vítimas;
  • para ajudar na divulgação de ferramentas disponíveis para acabar com o ciclo de violência de modo que elas sejam conhecidas pelo maior número possível de pessoas;

Como comunidade que quer ajudar no desenvolvimento de habilidades e carreiras de dados e analytics entendemos que parte desse diálogo deve ser feita sob a luz de dados — ou pelo menos discutindo a omissão deles.

Esse artigo tem como objetivo:

  1. apresentar as formas de violência contra a mulher;
    2. apresentar dados do Ministério da Mulher, da Família e dos Direitos Humanos;
    3. usar o pacote formattable para fazer uma tabela linda;
    4. fazer um mapa interativo simples com o número de ocorrências com o pacote leaflet;
    5. fazer um mapa interativo simples com a taxa de ocorrências por 100 mil habitantes com o pacote leaflet.

Estão previstos 05 categorias de violência doméstica e familiar contra a mulher na Lei Maria da Penha (Capítulo II, art. 7º, incisos I, II, III, IV e V) e descritas no site do Instituto Maria da Penha.

“Essas formas de agressão são complexas, perversas, não ocorrem isoladas umas das outras e têm graves consequências para a mulher. Qualquer uma delas constitui ato de violação dos direitos humanos e deve ser denunciada.”

Crimes de violência contra a mulher são comuns na sua ocorrência, mas pouco comuns em notificações e dados. Isso se deve:

  • à cultura patriarcal do país que considera a mulher como propriedade do homem;
  • à diminuição da gravidade de tais crimes, uma consequência do item acima;
  • ao receio de estigmatização da vítima;
  • dentre outros aspectos.

Para essa análise pegamos dados do Ministério da Mulher, da Família e dos Direitos Humanos, que dizem respeito às denúncias que são feitas pelo 180, Central de Atendimento à Mulher.

Depois de muito procurar cheguei nessa página, com um arquivo de dados tipo planilha. É imprescindível chamar atenção para que há dados referentes a Janeiro de 2018 a Junho de 2019. Ou seja, não são dados atualizados. Isso seria muito interessante uma vez que, segundo reportagens como essa, por exemplo, o isolamento imposto na pandemia do novo Coronavírus Covid 19 implicou aumento do número de casos de violência contra a mulher.

Como faz tempo que eu queria aprender a fazer uma tabela bonitinha vou começar explorando os dados da aba Denúncias usando o pacote formattable:

Dados do arquivo Denuncias_180___Janeiro_2018_a_Junho_2019site.xlsx, aba Denuncias.

O mais usual seria apresentar os dados como uma série temporal, aquele gráfico de linha que tem a variável de tempo no eixo-x e a variável de interesse no eixo-y.

Vamos começar LENDO OS DADOS.
Para ler a planilha com extensão xlsx optei pelo pacote readxl, do tidyverse:

den_temp <- readxl::read_excel("Denuncias_180___Janeiro_2018_a_Junho_2019site.xlsx", 
sheet = "Denuncias",
na = "N/A",
skip = 3,
trim_ws = TRUE,
col_types = c("text", rep("numeric", 19)),
col_names = c("type",
paste0(tolower(month.abb), 2018),
paste0(tolower(month.abb[1:6]), 2019),
"total")
)

Note que:

  • há um argumento para a aba de interesse: sheet;
  • explicitei o caracter usado para denotar observação não disponível: na;
  • disse que queria pular as três primeiras linhas: skip;
  • escolhi remover espaços em branco no começo ou fim de células: trim_ws,
  • disse as classes das colunas: col_types;
  • nomeei as colunas: col_names

E o objeto den_temp fica assim:

Objeto den_temp, imediatamente após a leitura dos dados com a função read_excel.

Como ainda ficaram linhas que fazem sentido na planiha, mas não fazem sentido no data.frame vou removê-las:

library(tidyr)
library(magrittr)
library(dplyr)
den_temp <- den_temp[-c(1:4),]den_temp %<>% drop_na(type)den_temp %<>%
slice(type = stringr::str_which(den_temp$type, pattern = "Legenda:", negate = TRUE)) %>%
slice(type = stringr::str_which(den_temp$type, pattern = "Obs:", negate = TRUE))
den_temp %<>%
slice(type = stringr::str_which(den_temp$type, pattern = "Obs:", negate = TRUE))
  • Eu tirei as 04 primeiras linhas explicitamente com a sintaxe da base;
  • Depois, eu removi as linha que são inteiras de NA com a função drop_na do pacote tidyr e sobrescrevi o objeto den_temp com o operador %<>% do pacote magrittr;
  • Também removi as linhas que tinham o termo “Legenda” com a função str_which do pacote stringr, função slice do pacote dplyr e operador %<>% do pacote magrittr;
  • E fiz o mesmo para as células que começam com Obs. Não sei porquê uma célula ficou então eu removi de novo.

Olha como melhorou:

Objeto den_temp, depois de remover linhas com NA, células com informações para legendas ou observações.

Preciso tratar um pouco os dados para criar variáveis/colunas que sejam interessantes. Vou usar o pacote dplyr, que já foi carregado anteriormente:

den_temp_tt <- den_temp %>% 
filter(type == "Total") %>%
select(-c(type, total)) %>%
pivot_longer(everything(), names_to = "month_year") %>%
mutate(total = sum(value),
perc = round(x = (value/total)*100, digits = 3),
mean = mean(value),
behind = lag(value),
decrease = if_else(value < behind, TRUE, FALSE),
below_avg = if_else(value < mean, TRUE, FALSE)) %>%
select(-c(mean, total, behind))
  • Escolhi mexer apenas com o total de notificações então filtrei o objeto para manter a linha em que a coluna type é igual a ‘Total’;
  • Tirei praticamente todas as colunas. Só selecionei as colunas type e total;
  • Passei esses dados para o formato longo com a função pivot_longer do pacote tidyr sendo a coluna ‘chave’ nomeada como month_year;
  • Criei colunas para representar:
    ** o total de ocorrências,
    ** o percentual de ocorrências em relação ao total,
    ** a média de ocorrências,
    ** uma quantidade auxiliar (chamada behind) que representa o número de ocorrências no mês anterior com a função lag do pacote dplyr,
    ** uma indicadora (chamada decrease) se o valor do mês i é inferior ao valor do mês i-1,
    ** uma indicadora (chamada below_avg) se o valor do mês i é inferior à média de ocorrências.
  • Removi as colunas ‘auxiliares’ mean, total e behind.

Esse objeto resumo:

Objeto que resume as quantidades relativas às denúncias.

Bora — finalmente — para a parte legal?! Vamos fazer a tabela linda com o pacote formattable:

library(formattable)formattable(den_temp_tt, 
list(
value = color_tile("white", "orange"),
area(col = perc) ~ normalize_bar("pink", 0.2),
decrease = formatter("span",
style = x ~ style(color = ifelse(x, "green", "red")),
x ~ icontext(ifelse(x, "plus", "minus"), ifelse(x, "Yes", "No"))),
below_avg = formatter("span",
style = x ~ style(color = ifelse(x, "green", "red")),
x ~ icontext(ifelse(x, "ok", "remove"), ifelse(x, "Yes", "No")))
)
)

Olha o resultado:

Tabela feita com o pacote formattable.

A função formattable deu apelo visual para a tabela:

  • Facilitou comparações entre quantidades;
  • Auxilia a leitura dos dados como, por exemplo, achar os meses com maiores valores de ocorrências.

Vamos descrever como ela foi usada:

  • O número de ocorrências (value) é colorido de modo a enfatizar a informação com a função color_tile;
  • O percentual (perc) é representado com uma barra rosa proporcional com as funções area e normalize_bar;
  • As informações de decréscimo do valor em um mês i com relação ao mês anterior (decrease) e se está abaixo do comportamento médio (below_avg) estão representadas na cor da fonte e com ícones (funções style e icontext)

É importante deixar bem claro que as quantidades descritas são pouco informativas e permitem nenhuma conclusão.

1. Avaliar o decréscimo de uma quantidade com relação à imediatamente anterior não revela uma informação particularmente útil.

2. Além disso, avaliar se o número de notificações está abaixo da média é simplista. Em se tratando de uma variável com conhecido comportamento de sub-notificação dizer que um mês está abaixo da média pode dizer que:

  • existiram menos ocorrências do crime, o que denota um fenômeno positivo;
  • existiram menos notificações do crime, o que significa que menos pessoas tiveram acesso e/ou coragem e/ou conhecimento para reportar um evento grave.

Então, trata-se de uma análise com intuito primordial de apresentar a base de dados, sua manipulação e uma funcionalidade interessantíssima.

No arquivo de dados existe outra aba com as quantidades de ocorrência por UF:

Dados do arquivo Denuncias_180___Janeiro_2018_a_Junho_2019site.xlsx, aba Denuncias por UF.

Vou fazer dois mapas:

  1. Para explorar os números absolutos:
    Como se trata da ocorrência de crimes tão cruéis, com inúmeros impactos para as vítimas é importante observar as contagens. Afinal cada vítima traz à luz um evento distinto, ajudando a revelar o cenário da cultura patriarcal e machista que precisamos enfrentar.
  2. Outro com as taxas de ocorrência por 100 mil habitantes:
    Os estados brasileiros diferem muito em quantidade de habitantes e observar a variável sob a forma de taxas auxilia a tornar comparável as quantidades por estado.

Vou ler os dados e tratar/manipular linhas e colunas como feito anteriormente:

den_uf <- readxl::read_excel("Denuncias_180___Janeiro_2018_a_Junho_2019site.xlsx", 
sheet = "Denuncias por UF",
na = "N/A",
skip = 7,
trim_ws = TRUE,
col_types = c("text", "text", rep("numeric", 4)),
col_names = c("uf",
"hab",
paste0("reg", 2018),
paste0("tx", 2018),
paste0("reg", 2019),
paste0("tx", 2019))
)
den_uf <- den_uf[-c(1:2),]den_uf %<>% drop_na(uf)den_uf %<>%
slice(uf = stringr::str_which(den_uf$uf, pattern = "Legenda:", negate = TRUE))
den_uf %<>%
slice(uf = stringr::str_which(den_uf$uf, pattern = "\\*", negate = TRUE))
den_uf %<>%
slice(uf = stringr::str_which(den_uf$uf, pattern = "Obs:", negate = TRUE))

Eu segui o post Criando um mapa do Brasil no R em 7 passos do Marcos Vinícius Fontes portanto, não vou entrar em detalhes.

Eu baixei os arquivos com os shapes para criar os mapas exatamente como ele sugere e deu tudo certo! Shapes são como listas do R. Objetos extremamente flexíveis, específicos para fazer mapas.

E instalei os pacotes para fazer os mapas conforme o código ia sendo executado, por vezes instalando dependências dos pacotes citados.

Começo lendo o arquivo shape (que baixei do IBGE exatamente como descrito no post) e atribuindo-o a um objeto com os pacotes rgdal e raster:

library(rgdal)shp <- raster::shapefile("mapa/BRUFE250GC_SIR.shp")

Para associar meus dados ao shape eu preciso de uma variável chave. Vou ler o arquivo csv que lista as siglas e código (a variável chave para ‘conversar’ com o shape) de cada UF:

ibge <- read.csv("mapa/estadosibge.csv", 
header = T, check.names = F, sep = ",",
col.names = c("codUF", "estado", "UF"),
stringsAsFactors = FALSE) %>%
select(contains("UF"))

Em seguida, faço a junção do objeto den_uf com o objeto ibge:

den_uf <- inner_join(x = den_uf, y = ibge, by = c("uf" = "UF"))

Note que a variável chave nesse caso é a sigla da UF e usei a função inner_join do pacote dplyr.

Depois, vou juntar den_uf com o shape shp e, nesse caso, usei a função merge da base e a variável chave é o código da UF:

den_uf <- merge(shp, den_uf, by.x = "CD_GEOCUF", by.y = "codUF")

Essa é a parte mais técnica. Vou ‘transformar’ o objeto den_uf atribuindo a ele atributos de projeção espacial. Em seguida, garanti que o Encoding da informação textual está adequado ao meu contexto de língua e SO (UTF-8).

proj4string(den_uf) <- sp::CRS("+proj=longlat +datum=WGS84 +no_defs") 
Encoding(den_uf$NM_ESTADO) <- "UTF-8"

Estamos quase no fim! Precisamos atribuir uma escala de cores para os nossos mapinhas e, mais uma vez, seguindo o post vou usar a paleta do pacote RColorBrewer:

library(RColorBrewer)
palPiYG <- colorBin("PiYG", domain = NULL, n = 7) #absoluto
palPRGn <- colorBin("PRGn", domain = NULL, n = 7) #taxa

Para os mapas utilizo o pacote leaflet.
Para as frequências absolutas:

library(leaflet)
reg2019 <- paste0("<strong>Estado: </strong>",
den_uf$NM_ESTADO,
"<br><strong>Pontos: </strong>",
den_uf$reg2019)
leaflet(data = den_uf) %>%
addProviderTiles("CartoDB.Positron") %>%
addPolygons(fillColor = ~ palPiYG(den_uf$reg2019),
fillOpacity = 1,
color = "#BDBDC3",
weight = 1,
popup = reg2019) %>%
addLegend("bottomright",
pal = palPiYG,
values = ~den_uf$reg2019,
title = "Ocorrências 2019",
opacity = 1)

O leaflet produz gráficos iterativos lindos! Olha como fica o mapa dos números absolutos (ordem alfabética dos nomes dos estados):

Na escala adotada:

  • as cores ROSADAS estão para contagens BAIXAS,
  • os tons CLAROS denotam contagens INTERMEDIÁRIAS e
  • as cores VERDES estão para contagens ALTAS

Na perspectiva das contagens os estados do Rio de Janeiro e São Paulo são os de maior número de ocorrências seguido de Minas Gerais, Bahia e Rio Grande do Sul. É muito nítido o predomínio de contagens inferiores nos estados das regiões Norte e Nordeste. Mas, como eu disse antes, é importante avaliar tais quantidades também como função de taxas populacionais, sobretudo quando o interesse é fazer comparações.

De modo análogo, o mapa para as taxas por 100 mil habitantes:

tx2019 <- paste0("<strong>Estado: </strong>", 
den_uf$NM_ESTADO,
"<br><strong>Pontos: </strong>",
den_uf$tx2019)
leaflet(data = den_uf) %>%
addProviderTiles("CartoDB.Positron") %>%
addPolygons(fillColor = ~ palPRGn(den_uf$tx2019),
fillOpacity = 0.99,
color = "#BDBDC3",
weight = 1,
popup = tx2019) %>%
addLegend("bottomright",
pal = palPRGn,
values = ~ den_uf$tx2019,
title = "Taxa/100mil hab. 2019",
opacity = 1)

E o resultado (estados em ordem alfabética):

Na escala adotada para as TAXAS:

  • os tons ROXOS estão para taxas BAIXAS,
  • as cores CLARAS denotam taxas INTERMEDIÁRIAS e
  • os tons VERDES demarcam taxas ALTAS

Levando em consideração o tamanho populacional os estado do Rio de Janeiro, Mato Grosso do Sul e o Distrito Federal aparecem como as Unidades com mais destaque (tons de verde). Goiás, Bahia e Espírito Santos tem valores médios e o Acre é o único estado na faixa mais inferior das taxas.

Falar sobre práticas de violência é extremamente necessário. Vida e segurança são direitos fundamentais assim como o de interromper eventuais ciclos de violência.

Se você está — ou conhece alguma pessoa que está — passando por episódios de violência como os descritos nesse artigo você precisa de ajuda ou deve acionar ajuda.

O R-Ladies BH não tem autonomia, autoridade ou competência para ajudar juridicamente ou psicologicamente, mas há algumas comunidades que podem apoiar ou esclarecer:

E, claro, não posso deixar de falar:

  • A Central de Atendimento à Mulher é um serviço criado para o combate à violência contra a mulher e oferece três tipos de atendimento: (01) registros de denúncias, (02) orientações para vítimas de violência e (03) informações sobre leis e campanhas.
    Ligue 180: Não se cale. Denuncie.

Referências:

Gostou desse texto? Clique em quantos aplausos — eles vão de 1 à 50 — você acredita que ele merece e deixe seu comentário!❤

Redes sociais: Instagram|YouTube|Facebook|Twitter

--

--