Introdução

Este tutorial visa demonstrar como extrair tabelas de arquivos pdf e realizar as transformações necessárias para análise dos dados sobre crimes violentos em Juiz de Fora.

Objetivos

  • Aprendizagem das ferramentas para manipulação de dados no R.
  • Representação gráfica dos crimes violentos em Juiz de Fora.

Recursos

Aplicativos

Embora de padrão aberto, o formato pdf não permite o processamento automatizado, sem que haja tratamento adequado através da ferramenta denominada “pdftools”, que é um conjunto de utilitários disponível para R, linguagem de programação flexível, utilizada para análise e visualização de dados, cuja interação pode feita por meio da linha de comando ou com o uso do RStudio, considerado o melhor ambiente de desenvolvimento de código em R.

Bibliotecas

Carregamos os pacotes adicionais a serem utilizados.

library(tidyverse)
library(pdftools)
library(reshape2)
library(RColorBrewer)
library(ggthemes)

Download do arquivo

Definimos as variáveis de trabalho:

url <- "http://www.geo.ufv.br/wp-content/uploads/2015/03/Marcelo-Aleixo-Mascarenhas.pdf"
pdf_file <- "violenciajf"

Baixamos o arquivo:

download.file(
  url, pdf_file, mode = "wb")

Tarefas de pré-processamento

Convertemos o arquivo pdf em arquivo texto e maiúsculas em minúsculas:

violencia <- pdf_text(pdf_file) %>%
  tolower()
  str(violencia)
##  chr [1:90] "        universidade federal de viçosa\n   centro de ciências humanas, letras e artes\n          departamento d"| __truncated__ ...

O resultado é uma lista com 90 elementos, de acordo com o número de páginas do arquivo. Então, configuramos a página desejada para importação, definimos a sequência ‘“\n”’ como separador de linhas, convertemos o tipo de dados de lista para vetor, removemos os espaços no início e final da linha e definimos o ponto e vírgula como separador de campo.

tab5 <- violencia[[49]] %>%
  str_split(pattern = "\n") %>%
  unlist() %>%
  str_trim() %>%
  str_replace_all("\\s{2,}", ";") 
tab5[1:20]
##  [1] "46"                                                                                    
##  [2] "inicia-se com um panorama geral de vítimas, subdivididas por crimes a que"             
##  [3] "foram sujeitas por semestre e ano em que tal delito ocorreu. em seguida, avaliam-se"   
##  [4] "as características pessoais de cada grupo de vítimas, devidamente subdivididas por"    
##  [5] "tipo de crime, visando identificar padrões entre estes."                               
##  [6] "tabela 5. quantitativo de envolvidos como vítimas de crimes violentos nos eventos de"  
##  [7] "defesa social (reds) registrados no município de juiz de fora de junho de 2009 à junho"
##  [8] "de 2014, crime, por semestre e ano do fato."                                           
##  [9] "crime;2º/09 1º/10 2º/10 1º/11 2º/11 1º/12 2º/12 1º/13 2º/13 1º/14 total"               
## [10] "roubo consumado;571;501;554;509;456;420;566;811;670;793;5851"                          
## [11] "homicidio tentado;64;60;63;69;91;73;111;162;116;116;925"                               
## [12] "homicidio consumado;22;25;29;27;20;24;47;61;59;76;390"                                 
## [13] "estupro consumado;34;39;50;12;18;22;23;17;27;23;265"                                   
## [14] "estupro tentado;14;19;17;1;4;5;5;5;3;6;79"                                             
## [15] "sequestro car. priv. consumado;4;7;7;3;5;4;8;3;5;11;57"                                
## [16] "extorsao med. seq. consumado;11;1;0;0;0;5;1;1;19"                                      
## [17] "sequestro e car. priv. tentado;0;0;1;0;0;0;0;0;0;0;1"                                  
## [18] "total;720;652;721;621;594;548;765 1060 880 1026 7587"                                  
## [19] "fonte: centro integrado de informações de defesa social (cinds)"                       
## [20] "tal como a relação de registro de eventos descrita no capítulo 4.2, a"

Extraímos a tabela 5, situada entre as strings “^crime” e “^total”; o metacaracter “^” indica que os padrões de busca devem ser localizados no início da linha.

tab_start <- stringr::str_which(tab5, "^crime")
tab_end <- stringr::str_which(tab5, "^total")
tbl5 <- tab5[(tab_start):(tab_end)]

tbl5
##  [1] "crime;2º/09 1º/10 2º/10 1º/11 2º/11 1º/12 2º/12 1º/13 2º/13 1º/14 total"
##  [2] "roubo consumado;571;501;554;509;456;420;566;811;670;793;5851"           
##  [3] "homicidio tentado;64;60;63;69;91;73;111;162;116;116;925"                
##  [4] "homicidio consumado;22;25;29;27;20;24;47;61;59;76;390"                  
##  [5] "estupro consumado;34;39;50;12;18;22;23;17;27;23;265"                    
##  [6] "estupro tentado;14;19;17;1;4;5;5;5;3;6;79"                              
##  [7] "sequestro car. priv. consumado;4;7;7;3;5;4;8;3;5;11;57"                 
##  [8] "extorsao med. seq. consumado;11;1;0;0;0;5;1;1;19"                       
##  [9] "sequestro e car. priv. tentado;0;0;1;0;0;0;0;0;0;0;1"                   
## [10] "total;720;652;721;621;594;548;765 1060 880 1026 7587"

Removemos o cabeçalho, que não casa com o critério de substituição, e a última linha, que contém os totalizadores verticais.

tbl5 <- tab5[(tab_start +1):(tab_end -1)]

tbl5
## [1] "roubo consumado;571;501;554;509;456;420;566;811;670;793;5851"
## [2] "homicidio tentado;64;60;63;69;91;73;111;162;116;116;925"     
## [3] "homicidio consumado;22;25;29;27;20;24;47;61;59;76;390"       
## [4] "estupro consumado;34;39;50;12;18;22;23;17;27;23;265"         
## [5] "estupro tentado;14;19;17;1;4;5;5;5;3;6;79"                   
## [6] "sequestro car. priv. consumado;4;7;7;3;5;4;8;3;5;11;57"      
## [7] "extorsao med. seq. consumado;11;1;0;0;0;5;1;1;19"            
## [8] "sequestro e car. priv. tentado;0;0;1;0;0;0;0;0;0;0;1"

Lemos o arquivo csv, excluímos a última coluna, que contém os totalizadores horizontais e adicionamos os cabeçalhos das colunas restantes.

text_con <- textConnection(tbl5)
tbl5 <- read.csv(text_con, sep = ";", header = FALSE)
tbl5 <- tbl5[-c(12)]
colnames(tbl5) <- c("Tipologia", "2º/09", "1º/10", "2º/10", "1º/11", "2º/11", "1º/12", "2º/12", "1º/13", "2º/13", "1º/14")

tbl5
##                        Tipologia 2º/09 1º/10 2º/10 1º/11 2º/11 1º/12 2º/12
## 1                roubo consumado   571   501   554   509   456   420   566
## 2              homicidio tentado    64    60    63    69    91    73   111
## 3            homicidio consumado    22    25    29    27    20    24    47
## 4              estupro consumado    34    39    50    12    18    22    23
## 5                estupro tentado    14    19    17     1     4     5     5
## 6 sequestro car. priv. consumado     4     7     7     3     5     4     8
## 7   extorsao med. seq. consumado    11     1     0     0     0     5     1
## 8 sequestro e car. priv. tentado     0     0     1     0     0     0     0
##   1º/13 2º/13 1º/14
## 1   811   670   793
## 2   162   116   116
## 3    61    59    76
## 4    17    27    23
## 5     5     3     6
## 6     3     5    11
## 7     1    19    NA
## 8     0     0     0
str(tbl5)
## 'data.frame':    8 obs. of  11 variables:
##  $ Tipologia: chr  "roubo consumado" "homicidio tentado" "homicidio consumado" "estupro consumado" ...
##  $ 2º/09    : int  571 64 22 34 14 4 11 0
##  $ 1º/10    : int  501 60 25 39 19 7 1 0
##  $ 2º/10    : int  554 63 29 50 17 7 0 1
##  $ 1º/11    : int  509 69 27 12 1 3 0 0
##  $ 2º/11    : int  456 91 20 18 4 5 0 0
##  $ 1º/12    : int  420 73 24 22 5 4 5 0
##  $ 2º/12    : int  566 111 47 23 5 8 1 0
##  $ 1º/13    : int  811 162 61 17 5 3 1 0
##  $ 2º/13    : int  670 116 59 27 3 5 19 0
##  $ 1º/14    : int  793 116 76 23 6 11 NA 0

Reestruturação dos dados

Temos então uma estrutura de dados do tipo data.frame, com onze variáveis, alinhadas segundo o eixo horizontal, de modo a facilitar a inserção da tabela no texto da monografia. Contudo, a nosso ver, esta moldura não representa adequadamente o conjunto das observações. Por isso, consideramos mais conveniente a seguinte esquematização:
a. Tipologia: variável categórica, em que os valores assumidos representam classes de incidentes violentos;
b. Intervalo: variável relacionada ao tempo, que indica o período de referência;
c. Vítimas: variável discreta que mede o número de incidentes violentos em determinado período.

Assim dispomos de uma nova configuração dos dados.

tbl5 <- melt(tbl5, id.vars = c("Tipologia"), variable.name = "Intervalo", value.name = "Vítimas")

str(tbl5)
## 'data.frame':    80 obs. of  3 variables:
##  $ Tipologia: chr  "roubo consumado" "homicidio tentado" "homicidio consumado" "estupro consumado" ...
##  $ Intervalo: Factor w/ 10 levels "2º/09","1º/10",..: 1 1 1 1 1 1 1 1 2 2 ...
##  $ Vítimas  : int  571 64 22 34 14 4 11 0 501 60 ...

Modificamos os nomes utilizados para identificar as classes da variável categórica:

tbl5$Tipologia <- recode(tbl5$Tipologia,
                         'estupro consumado' = "estupro",
                         'estupro tentado' = "tentativa de estupro",
                         'extorsao med. seq. consumado' = "extorsão",
                         'homicidio consumado' = "homicídio",
                         'homicidio tentado' = "tentativa de homicídio",
                         'roubo consumado' = "roubo",
                         'sequestro car. priv. consumado' = "sequestro",
                         'sequestro e car. priv. tentado' = "tentativa de sequestro")



Uma pequena amostra dá idéia da transformação precedente:

head(tbl5, n=8)
##                Tipologia Intervalo Vítimas
## 1                  roubo     2º/09     571
## 2 tentativa de homicídio     2º/09      64
## 3              homicídio     2º/09      22
## 4                estupro     2º/09      34
## 5   tentativa de estupro     2º/09      14
## 6              sequestro     2º/09       4
## 7               extorsão     2º/09      11
## 8 tentativa de sequestro     2º/09       0

Dados agregados

Podemos gerar subconjuntos para cada um dos vetores do data.frame:

oporc <- aggregate(Vítimas ~ Tipologia, data = tbl5, FUN = sum, na.rm = TRUE)
opors <- aggregate(Vítimas ~ Intervalo, data = tbl5, FUN = sum, na.rm = TRUE)


De tal maneira que chegamos ao ponto de responder algumas perguntas.

“Quantas são as vítimas por categoria, durante todo o período?”"

oporc
##                Tipologia Vítimas
## 1                estupro     265
## 2               extorsão      38
## 3              homicídio     390
## 4                  roubo    5851
## 5              sequestro      57
## 6   tentativa de estupro      79
## 7 tentativa de homicídio     925
## 8 tentativa de sequestro       1


“Quantas são as vítimas por semestre, somadas todas as categorias”

opors
##    Intervalo Vítimas
## 1      2º/09     720
## 2      1º/10     652
## 3      2º/10     721
## 4      1º/11     621
## 5      2º/11     594
## 6      1º/12     553
## 7      2º/12     761
## 8      1º/13    1060
## 9      2º/13     899
## 10     1º/14    1025

Visualização dos dados

Linhas de tendência

gl <- ggplot(tbl5, aes(x=Intervalo, y=Vítimas, colour=Tipologia, group=Tipologia)) +
  geom_line(linetype="solid", size=1.5) +
  geom_point() +
  ggtitle("Índice de Criminalidade Violenta: Juiz de Fora (2009/2014)") +
  theme_dark() +
  theme(plot.title = element_text(size = 12, face = "bold")) +
  theme(legend.position = "right") +
  scale_colour_brewer("Tipologia", palette="Set2") +
  xlab("") +
  ylab("") +
  labs(caption = "Fonte: Mascarenhas(2014)")

gl 

Gráfico de barras por semestre

gops <- ggplot(opors, aes(Intervalo, Vítimas, fill = Intervalo)) +
  geom_bar(stat = "identity") +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  guides(fill = F)

gops

Gráfico de barras por categoria

gopc <- ggplot(oporc, aes(x = reorder(Tipologia, +Vítimas), y = Vítimas)) +
  geom_bar(stat = "identity", fill = "black") 
  
gopc + coord_flip() +
        theme(axis.text.y = element_text(size=rel (1.2))) +
        xlab("")

Gráfico de barras empilhadas

Para comparar a proporção de cada classe em relação ao total de ocorrências, por semestre, utilizamos o gráfico de barras empilhadas.

gopse <- ggplot(tbl5, aes(x=Intervalo, y=Vítimas, fill=Tipologia)) +
  geom_bar(stat = "identity", position = "fill") +
  theme(axis.text.x = element_text(angle = 25, hjust = 1),
        legend.position = "right") +
  xlab("") +
  ylab("")

gopse


Referências:

Kabacoff, R. (2011). R in action: Data analysis and graphics with R.

Mascarenhas, M. A. (2014) Vitimologia nos crimes violentos em Juiz de Fora: Uma abordagem geográfica. Monografia (Bacharelado em Geografia), UFV. Disponível em: http://www.geo.ufv.br/wp-content/uploads/2015/03/Marcelo-Aleixo-Mascarenhas.pdf. Acessado pela última vez em: 18/03/2019.

Zumel, N. and Mount, J. (2014). Practical Data Science with R.