├── vignettes ├── .gitignore ├── header.tex ├── br_crime_predict.pdf ├── acess_dados_criminais_vde.pdf ├── br_crime_predict.Rmd └── acess_dados_criminais_vde.Rmd ├── data-raw ├── log_status.txt ├── pop_projetada_anual.xlsx ├── pop_projetada_mensal_dia_15.xlsx ├── indicadoressegurancapublicauf.xlsx └── base_sinesp_vde.R ├── LICENSE ├── R ├── sysdata.rda ├── get_sinesp_vde_data.R └── br_crime_predict.R ├── man ├── figures │ ├── figure.png │ ├── mapa.png │ └── grafico.png ├── br_crime_predict.Rd └── get_sinesp_vde_data.Rd ├── CRAN-SUBMISSION ├── cran-comments.md ├── tests ├── testthat │ ├── testthat-problems.rds │ ├── test-get_sinesp_data.R │ └── test-get_sinesp_vde_data.R └── testthat.R ├── .gitignore ├── .Rbuildignore ├── NAMESPACE ├── inst ├── THANKS └── extdata │ └── ufs.csv ├── BrazilCrime.Rproj ├── LICENSE.md ├── DESCRIPTION ├── .github └── workflows │ └── rhub.yaml └── README.md /vignettes/.gitignore: -------------------------------------------------------------------------------- 1 | *.html 2 | *.R 3 | -------------------------------------------------------------------------------- /vignettes/header.tex: -------------------------------------------------------------------------------- 1 | \usepackage{booktabs} -------------------------------------------------------------------------------- /data-raw/log_status.txt: -------------------------------------------------------------------------------- 1 | Existem novos dados no SINESP VDE 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | YEAR: 2024 2 | COPYRIGHT HOLDER: BrazilCrime authors 3 | -------------------------------------------------------------------------------- /R/sysdata.rda: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GiovanniVargette/BrazilCrime/HEAD/R/sysdata.rda -------------------------------------------------------------------------------- /man/figures/figure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GiovanniVargette/BrazilCrime/HEAD/man/figures/figure.png -------------------------------------------------------------------------------- /man/figures/mapa.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GiovanniVargette/BrazilCrime/HEAD/man/figures/mapa.png -------------------------------------------------------------------------------- /man/figures/grafico.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GiovanniVargette/BrazilCrime/HEAD/man/figures/grafico.png -------------------------------------------------------------------------------- /CRAN-SUBMISSION: -------------------------------------------------------------------------------- 1 | Version: 0.21 2 | Date: 2024-09-14 00:51:00 UTC 3 | SHA: c225766d936f8a03689531c9fc964dfc66979ec0 4 | -------------------------------------------------------------------------------- /cran-comments.md: -------------------------------------------------------------------------------- 1 | ## R CMD check results 2 | 3 | 0 errors | 0 warnings | 1 note 4 | 5 | * This is a new release. 6 | -------------------------------------------------------------------------------- /vignettes/br_crime_predict.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GiovanniVargette/BrazilCrime/HEAD/vignettes/br_crime_predict.pdf -------------------------------------------------------------------------------- /data-raw/pop_projetada_anual.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GiovanniVargette/BrazilCrime/HEAD/data-raw/pop_projetada_anual.xlsx -------------------------------------------------------------------------------- /tests/testthat/testthat-problems.rds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GiovanniVargette/BrazilCrime/HEAD/tests/testthat/testthat-problems.rds -------------------------------------------------------------------------------- /vignettes/acess_dados_criminais_vde.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GiovanniVargette/BrazilCrime/HEAD/vignettes/acess_dados_criminais_vde.pdf -------------------------------------------------------------------------------- /data-raw/pop_projetada_mensal_dia_15.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GiovanniVargette/BrazilCrime/HEAD/data-raw/pop_projetada_mensal_dia_15.xlsx -------------------------------------------------------------------------------- /data-raw/indicadoressegurancapublicauf.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GiovanniVargette/BrazilCrime/HEAD/data-raw/indicadoressegurancapublicauf.xlsx -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .Rproj.user 2 | .Rhistory 3 | .Rdata 4 | .httr-oauth 5 | .DS_Store 6 | data-raw/raw-sinesp-vde-data/ 7 | /doc/ 8 | /Meta/ 9 | inst/doc 10 | -------------------------------------------------------------------------------- /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^BrazilCrime\.Rproj$ 2 | ^\.Rproj\.user$ 3 | ^LICENSE\.md$ 4 | ^data-raw$ 5 | ^CRAN-SUBMISSION$ 6 | ^cran-comments\.md$ 7 | ^.github$ 8 | ^doc$ 9 | ^Meta$ 10 | -------------------------------------------------------------------------------- /NAMESPACE: -------------------------------------------------------------------------------- 1 | # Generated by roxygen2: do not edit by hand 2 | 3 | export(br_crime_predict) 4 | export(get_sinesp_vde_data) 5 | importFrom(stats,setNames) 6 | importFrom(stats,ts) 7 | -------------------------------------------------------------------------------- /inst/THANKS: -------------------------------------------------------------------------------- 1 | Marcelo Justus agradece ao CNPq pela Bolsa de Produtividade em Pesquisa (processo nº 312685/2021-1), que viabilizou a realização deste trabalho. Giovanni agradece ao CNPq pelas Bolsas de Iniciação Científica recebidas de 2023 a 2025, fundamentais para sua participação neste projeto. 2 | -------------------------------------------------------------------------------- /tests/testthat.R: -------------------------------------------------------------------------------- 1 | # This file is part of the standard setup for testthat. 2 | # It is recommended that you do not modify it. 3 | # 4 | # Where should you do additional test configuration? 5 | # Learn more about the roles of various files in: 6 | # * https://r-pkgs.org/testing-design.html#sec-tests-files-overview 7 | # * https://testthat.r-lib.org/articles/special-files.html 8 | 9 | library(testthat) 10 | library(BrazilCrime) 11 | 12 | test_check("BrazilCrime") 13 | -------------------------------------------------------------------------------- /inst/extdata/ufs.csv: -------------------------------------------------------------------------------- 1 | uf,uf_abrev 2 | Acre,AC 3 | Alagoas,AL 4 | Amapá,AP 5 | Amazonas,AM 6 | Bahia,BA 7 | Ceará,CE 8 | Distrito Federal,DF 9 | Espírito Santo,ES 10 | Goiás,GO 11 | Maranhão,MA 12 | Mato Grosso,MT 13 | Mato Grosso do Sul,MS 14 | Minas Gerais,MG 15 | Paraná,PR 16 | Paraíba,PB 17 | Pará,PA 18 | Pernambuco,PE 19 | Piauí,PI 20 | Rio Grande do Norte,RN 21 | Rio Grande do Sul,RS 22 | Rio de Janeiro,RJ 23 | Rondônia,RO 24 | Roraima,RR 25 | Santa Catarina,SC 26 | Sergipe,SE 27 | São Paulo,SP 28 | Tocantins,TO 29 | -------------------------------------------------------------------------------- /BrazilCrime.Rproj: -------------------------------------------------------------------------------- 1 | Version: 1.0 2 | 3 | RestoreWorkspace: No 4 | SaveWorkspace: No 5 | AlwaysSaveHistory: Default 6 | 7 | EnableCodeIndexing: Yes 8 | UseSpacesForTab: Yes 9 | NumSpacesForTab: 2 10 | Encoding: UTF-8 11 | 12 | RnwWeave: Sweave 13 | LaTeX: pdfLaTeX 14 | 15 | AutoAppendNewline: Yes 16 | StripTrailingWhitespace: Yes 17 | LineEndingConversion: Posix 18 | 19 | BuildType: Package 20 | PackageUseDevtools: Yes 21 | PackageInstallArgs: --no-multiarch --with-keep.source 22 | PackageCheckArgs: --as-cran 23 | PackageRoxygenize: rd,collate,namespace 24 | -------------------------------------------------------------------------------- /man/br_crime_predict.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/br_crime_predict.R 3 | \name{br_crime_predict} 4 | \alias{br_crime_predict} 5 | \title{br_crime_predict Function} 6 | \usage{ 7 | br_crime_predict(dados, ts_col, freq = "monthly", h = 12, level = 95) 8 | } 9 | \arguments{ 10 | \item{dados}{Data.frame contendo as colunas da serie: evento, uf, municipio, data, e uma coluna com os valores numericos.} 11 | 12 | \item{ts_col}{Nome da coluna (string) com os dados da serie temporal (ex: "total_vitima").} 13 | 14 | \item{freq}{Frequencia temporal: "monthly" ou "yearly". Padrao e "monthly".} 15 | 16 | \item{h}{Horizonte da previsao. Padrao: 12.} 17 | 18 | \item{level}{Nivel de confianca do intervalo de previsao. Padrão: 95.} 19 | 20 | \item{log}{Logico. Se TRUE, aplica transformacao logaritmica. Padrao: FALSE.} 21 | } 22 | \value{ 23 | Lista com modelo ajustado, previsao e grafico ggplot2. 24 | } 25 | \description{ 26 | Performs automatic ARIMA modeling and forecasting on crime time series data. 27 | } 28 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | # MIT License 2 | 3 | Copyright (c) 2024 BrazilCrime authors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /man/get_sinesp_vde_data.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/get_sinesp_vde_data.R 3 | \name{get_sinesp_vde_data} 4 | \alias{get_sinesp_vde_data} 5 | \title{get_sinesp_vde_data Function} 6 | \usage{ 7 | get_sinesp_vde_data( 8 | state = "all", 9 | city = "all", 10 | year = "all", 11 | category = "all", 12 | typology = "all", 13 | granularity = "month" 14 | ) 15 | } 16 | \arguments{ 17 | \item{state}{State to be filtered. Character or vector. Default is "all".} 18 | 19 | \item{city}{City to be filtered. Character or vector. Default is "all".} 20 | 21 | \item{year}{Year(s) of the crime. Integer or vector. Default is "all".} 22 | 23 | \item{category}{Crime category. Character or vector. Default is "all".} 24 | 25 | \item{typology}{Crime typology (e.g., "Furto de veículo"). Character or vector. Default is "all".} 26 | 27 | \item{granularity}{Level of temporal granularity: "year" or "month". Default is "month".} 28 | } 29 | \value{ 30 | A data frame with the filtered or summarized data. 31 | } 32 | \description{ 33 | This function collects criminal data from the SINESP VDE database (2015–2024). 34 | It supports filtering by state, city, year, crime category and typology. 35 | } 36 | \examples{ 37 | \donttest{ 38 | dados <- get_sinesp_vde_data(state = "SP", year = 2020:2022) 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /tests/testthat/test-get_sinesp_data.R: -------------------------------------------------------------------------------- 1 | library(testthat) 2 | library(BrazilCrime) 3 | 4 | # test_that("get_sinesp_data downloads and processes data correctly", { 5 | # 6 | # dados <- get_sinesp_data() 7 | # expect_true(is.data.frame(dados)) 8 | # 9 | # expected_columns <- c("uf", "uf_abrev", "tipo_crime", "ano", "mes", "ocorrencias") 10 | # expect_true(all(expected_columns %in% colnames(dados))) 11 | # 12 | # 13 | # dados_sp <- get_sinesp_data(state = "SP") 14 | # expect_true(all(dados_sp$uf_abrev == "SP")) 15 | # 16 | # dados_roubo <- get_sinesp_data(typology = "Roubo de veículo") 17 | # expect_true(all(dados_roubo$tipo_crime == "Roubo de veículo")) 18 | # 19 | # dados_2020 <- get_sinesp_data(year = 2020) 20 | # expect_true(all(dados_2020$ano == 2020)) 21 | # 22 | # dados_anual <- get_sinesp_data(granularity = "year") 23 | # expect_true("ano" %in% colnames(dados_anual)) 24 | # expect_false("mes" %in% colnames(dados_anual)) 25 | # 26 | # dados_relativos <- get_sinesp_data(relative_values = TRUE) 27 | # expect_true("ocorrencias_100k_hab" %in% colnames(dados_relativos)) 28 | # 29 | # dados_geom <- get_sinesp_data(geom = TRUE) 30 | # expect_true("geometry" %in% colnames(dados_geom)) 31 | # 32 | # dados_pivot <- get_sinesp_data(pivot = TRUE) 33 | # expect_true("roubo_de_veiculo" %in% colnames(dados_pivot)) 34 | # }) 35 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: BrazilCrime 2 | Title: Accesses Brazilian Public Security Data from SINESP Since 2015 3 | Version: 0.3.0 4 | Authors@R: 5 | c( 6 | person("Giovanni", "Vargette", , "g216978@dac.unicamp.br", role = c("aut", "cre"), 7 | comment = c(ORCID = "https://orcid.org/0009-0006-8164-5274")), 8 | person("Igor", "Laltuf", , "igorlaltuf@gmail.com", role = c("aut"), 9 | comment = c(ORCID = "https://orcid.org/0000-0002-5614-4404")), 10 | person("Marcelo", "Justus", , "mjustus@unicamp.br", role = c("aut"), 11 | comment = c(ORCID = "https://orcid.org/0000-0001-8660-1779"))) 12 | Maintainer: Giovanni Vargette 13 | Description: Allows access to data from the Brazilian Public Security Information System (SINESP) by state and municipality. It should be emphasized that the package only extracts the data and facilitates its manipulation in R. Therefore, its sole purpose is to support empirical research. All data credits belong to SINESP, an integrated information platform developed and maintained by the National Secretariat of Public Security (SENASP) of the Ministry of Justice and Public Security. . 14 | License: MIT + file LICENSE 15 | Encoding: UTF-8 16 | Roxygen: list(markdown = TRUE) 17 | RoxygenNote: 7.3.3 18 | VignetteBuilder: knitr 19 | Imports: 20 | dplyr, 21 | forecast, 22 | ggplot2 23 | Depends: 24 | R (>= 4.1.0) 25 | LazyData: true 26 | LazyDataCompression: xz 27 | Suggests: 28 | knitr, 29 | rmarkdown, 30 | bookdown, 31 | kableExtra, 32 | tidyr, 33 | stringr, 34 | ggcorrplot, 35 | formatR, 36 | lubridate, 37 | testthat (>= 3.0.0) 38 | Config/testthat/edition: 3 39 | -------------------------------------------------------------------------------- /tests/testthat/test-get_sinesp_vde_data.R: -------------------------------------------------------------------------------- 1 | library(testthat) 2 | library(BrazilCrime) 3 | 4 | test_that("get_sinesp_vde_data returns a data frame", { 5 | result <- get_sinesp_vde_data() 6 | expect_s3_class(result, "data.frame") 7 | print('Test data type') 8 | }) 9 | 10 | test_that("get_sinesp_vde_data filters correctly by state", { 11 | result <- get_sinesp_vde_data(state = "SP") 12 | unique_states <- unique(result$uf) 13 | expect_true(all(unique_states == "SP")) 14 | print('Test state argument') 15 | }) 16 | 17 | test_that("get_sinesp_vde_data filters correctly by city", { 18 | result <- get_sinesp_vde_data(state = "SP", city = "São Paulo") 19 | unique_cities <- tolower(unique(result$municipio)) 20 | expect_true(all(unique_cities == "são paulo")) 21 | print('Test city argument') 22 | }) 23 | 24 | test_that("get_sinesp_vde_data stops if city is selected without state", { 25 | expect_error(get_sinesp_vde_data(city = "São Paulo"), "To select a city, it is necessary to select a state first.") 26 | print('Test city and state arguments') 27 | }) 28 | 29 | test_that("get_sinesp_vde_data filters correctly by category", { 30 | result <- get_sinesp_vde_data(category = "vitimas") 31 | unique_categories <- unique(result$categoria) 32 | expect_true(all(unique_categories == "vitimas")) 33 | print('Test category argument') 34 | }) 35 | 36 | test_that("get_sinesp_vde_data filters correctly by typology", { 37 | result <- get_sinesp_vde_data(category = "vitimas", typology = "Estupro") 38 | unique_typologies <- unique(result$evento) 39 | expect_true(all(unique_typologies == "Estupro")) 40 | print('Test typology argument') 41 | }) 42 | 43 | test_that("get_sinesp_vde_data summarizes correctly by year", { 44 | result <- get_sinesp_vde_data(granularity = 'year') 45 | expect_true("ano" %in% colnames(result)) 46 | print('Test granularity argument') 47 | }) 48 | -------------------------------------------------------------------------------- /R/get_sinesp_vde_data.R: -------------------------------------------------------------------------------- 1 | #' get_sinesp_vde_data Function 2 | #' 3 | #' This function collects criminal data from the SINESP VDE database (2015–2024). 4 | #' It supports filtering by state, city, year, crime category and typology. 5 | #' 6 | #' @param state State to be filtered. Character or vector. Default is "all". 7 | #' @param city City to be filtered. Character or vector. Default is "all". 8 | #' @param year Year(s) of the crime. Integer or vector. Default is "all". 9 | #' @param category Crime category. Character or vector. Default is "all". 10 | #' @param typology Crime typology (e.g., "Furto de veículo"). Character or vector. Default is "all". 11 | #' @param granularity Level of temporal granularity: "year" or "month". Default is "month". 12 | #' 13 | #' @return A data frame with the filtered or summarized data. 14 | #' 15 | #' @examples 16 | #' \donttest{ 17 | #' dados <- get_sinesp_vde_data(state = "SP", year = 2020:2022) 18 | #' } 19 | #' @export 20 | get_sinesp_vde_data <- function(state = 'all', city = "all", 21 | year = 'all', category = "all", 22 | typology = 'all', granularity = 'month') { 23 | 24 | uf <- municipio <- ano <- mes <- categoria <- evento <- NULL 25 | df <- sinesp_vde_data 26 | 27 | # --- Função de filtro mais robusta 28 | filter_data <- function(df, category, typology, city, state, year) { 29 | if (!identical(state, "all")) { 30 | df <- df |> 31 | dplyr::filter(tolower(uf) %in% tolower(state)) 32 | 33 | if (!identical(city, "all") && !identical(city, FALSE)) { 34 | df <- df |> 35 | dplyr::filter(tolower(municipio) %in% tolower(city)) 36 | } 37 | } else { 38 | if (!identical(city, "all")) { 39 | stop("To select a city, it is necessary to select a state first.") 40 | } 41 | } 42 | 43 | if (!identical(year, "all")) { 44 | df <- df |> 45 | dplyr::filter(ano %in% year) 46 | } 47 | 48 | if (!identical(category, "all")) { 49 | df <- df |> 50 | dplyr::filter(tolower(categoria) %in% tolower(category)) 51 | } 52 | 53 | if (!identical(typology, "all")) { 54 | df <- df |> 55 | dplyr::filter(tolower(evento) %in% tolower(typology)) 56 | } 57 | 58 | df 59 | } 60 | 61 | # --- Aplicar filtros 62 | df <- filter_data(df, category, typology, city, state, year) 63 | 64 | # Criar coluna 'data' no formato YYYY-MM como Date 65 | if ("ano" %in% names(df) && "mes" %in% names(df)) { 66 | df$data <- lubridate::ym(paste(df$ano, stringr::str_pad(df$mes, 2, pad = "0"))) 67 | } 68 | 69 | message("Query completed.") 70 | old <- options(timeout = 60) 71 | on.exit(options(old)) 72 | return(df) 73 | } 74 | -------------------------------------------------------------------------------- /.github/workflows/rhub.yaml: -------------------------------------------------------------------------------- 1 | # R-hub's generic GitHub Actions workflow file. It's canonical location is at 2 | # https://github.com/r-hub/actions/blob/v1/workflows/rhub.yaml 3 | # You can update this file to a newer version using the rhub2 package: 4 | # 5 | # rhub::rhub_setup() 6 | # 7 | # It is unlikely that you need to modify this file manually. 8 | 9 | name: R-hub 10 | run-name: "${{ github.event.inputs.id }}: ${{ github.event.inputs.name || format('Manually run by {0}', github.triggering_actor) }}" 11 | 12 | on: 13 | workflow_dispatch: 14 | inputs: 15 | config: 16 | description: 'A comma separated list of R-hub platforms to use.' 17 | type: string 18 | default: 'linux,windows,macos' 19 | name: 20 | description: 'Run name. You can leave this empty now.' 21 | type: string 22 | id: 23 | description: 'Unique ID. You can leave this empty now.' 24 | type: string 25 | 26 | jobs: 27 | 28 | setup: 29 | runs-on: ubuntu-latest 30 | outputs: 31 | containers: ${{ steps.rhub-setup.outputs.containers }} 32 | platforms: ${{ steps.rhub-setup.outputs.platforms }} 33 | 34 | steps: 35 | # NO NEED TO CHECKOUT HERE 36 | - uses: r-hub/actions/setup@v1 37 | with: 38 | config: ${{ github.event.inputs.config }} 39 | id: rhub-setup 40 | 41 | linux-containers: 42 | needs: setup 43 | if: ${{ needs.setup.outputs.containers != '[]' }} 44 | runs-on: ubuntu-latest 45 | name: ${{ matrix.config.label }} 46 | strategy: 47 | fail-fast: false 48 | matrix: 49 | config: ${{ fromJson(needs.setup.outputs.containers) }} 50 | container: 51 | image: ${{ matrix.config.container }} 52 | 53 | steps: 54 | - uses: r-hub/actions/checkout@v1 55 | - uses: r-hub/actions/platform-info@v1 56 | with: 57 | token: ${{ secrets.RHUB_TOKEN }} 58 | job-config: ${{ matrix.config.job-config }} 59 | - uses: r-hub/actions/setup-deps@v1 60 | with: 61 | token: ${{ secrets.RHUB_TOKEN }} 62 | job-config: ${{ matrix.config.job-config }} 63 | - uses: r-hub/actions/run-check@v1 64 | with: 65 | token: ${{ secrets.RHUB_TOKEN }} 66 | job-config: ${{ matrix.config.job-config }} 67 | 68 | other-platforms: 69 | needs: setup 70 | if: ${{ needs.setup.outputs.platforms != '[]' }} 71 | runs-on: ${{ matrix.config.os }} 72 | name: ${{ matrix.config.label }} 73 | strategy: 74 | fail-fast: false 75 | matrix: 76 | config: ${{ fromJson(needs.setup.outputs.platforms) }} 77 | 78 | steps: 79 | - uses: r-hub/actions/checkout@v1 80 | - uses: r-hub/actions/setup-r@v1 81 | with: 82 | job-config: ${{ matrix.config.job-config }} 83 | token: ${{ secrets.RHUB_TOKEN }} 84 | - uses: r-hub/actions/platform-info@v1 85 | with: 86 | token: ${{ secrets.RHUB_TOKEN }} 87 | job-config: ${{ matrix.config.job-config }} 88 | - uses: r-hub/actions/setup-deps@v1 89 | with: 90 | job-config: ${{ matrix.config.job-config }} 91 | token: ${{ secrets.RHUB_TOKEN }} 92 | - uses: r-hub/actions/run-check@v1 93 | with: 94 | job-config: ${{ matrix.config.job-config }} 95 | token: ${{ secrets.RHUB_TOKEN }} 96 | -------------------------------------------------------------------------------- /R/br_crime_predict.R: -------------------------------------------------------------------------------- 1 | #' br_crime_predict Function 2 | #' 3 | #' Performs automatic ARIMA modeling and forecasting on crime time series data. 4 | #' 5 | #' @param dados Data.frame contendo as colunas da serie: evento, uf, municipio, data, e uma coluna com os valores numericos. 6 | #' @param ts_col Nome da coluna (string) com os dados da serie temporal (ex: "total_vitima"). 7 | #' @param freq Frequencia temporal: "monthly" ou "yearly". Padrao e "monthly". 8 | #' @param h Horizonte da previsao. Padrao: 12. 9 | #' @param log Logico. Se TRUE, aplica transformacao logaritmica. Padrao: FALSE. 10 | #' @param level Nivel de confianca do intervalo de previsao. Padrão: 95. 11 | #' 12 | #' @return Lista com modelo ajustado, previsao e grafico ggplot2. 13 | #' @importFrom stats ts setNames 14 | #' @export 15 | 16 | br_crime_predict <- function(dados, ts_col, freq = "monthly", h = 12, level = 95) { 17 | if (missing(dados) || missing(ts_col)) { 18 | stop("Voce deve fornecer o data.frame 'dados' e o nome da coluna da serie temporal ('ts_col')") 19 | } 20 | 21 | # Verificar colunas obrigatórias 22 | if (!all(c("data", "evento", "municipio", "uf") %in% names(dados))) { 23 | stop("O data.frame 'dados' deve conter as colunas: data, evento, municipio e uf") 24 | } 25 | 26 | # Converter data 27 | if (is.character(dados$data)) { 28 | dados$data <- lubridate::ym(dados$data) 29 | } else if (inherits(dados$data, "Date")) { 30 | dados$data <- lubridate::ym(format(dados$data, "%Y-%m")) 31 | } else { 32 | stop("A coluna 'data' deve estar no formato 'YYYY-MM' ou ser do tipo Date") 33 | } 34 | 35 | # Série numérica 36 | ts_data <- dados[[ts_col]] 37 | 38 | # Conversão para objeto ts 39 | message("Convertendo dados para objeto 'ts'") 40 | start_year <- lubridate::year(min(dados$data)) 41 | start_period <- if (freq == "monthly") lubridate::month(min(dados$data)) else 1 42 | frequency <- if (freq == "monthly") 12 else 1 43 | 44 | ts_obj <- ts(ts_data, start = c(start_year, start_period), frequency = frequency) 45 | 46 | # Ajuste do modelo ARIMA com BIC fixado 47 | model <- forecast::auto.arima( 48 | ts_obj, 49 | lambda = "auto", 50 | stepwise = TRUE, 51 | trace = FALSE, 52 | approximation = FALSE, 53 | allowdrift = TRUE, 54 | allowmean = TRUE, 55 | ic = "bic" 56 | ) 57 | 58 | # Previsão 59 | fcast <- forecast::forecast(model, h = h, level = level) 60 | 61 | # Preparar datas futuras 62 | future_dates <- seq.Date(from = max(dados$data), by = "month", length.out = h) 63 | full_dates <- c(dados$data, future_dates) 64 | 65 | # Preparar data.frame do gráfico 66 | df_plot <- data.frame( 67 | date = full_dates, 68 | value = c(ts_data, rep(NA, h)), 69 | fitted = c(as.numeric(model$fitted), rep(NA, h)), 70 | forecast = c(rep(NA, length(ts_data)), as.numeric(fcast$mean)), 71 | lower = c(rep(NA, length(ts_data)), fcast$lower[, 1]), 72 | upper = c(rep(NA, length(ts_data)), fcast$upper[, 1]) 73 | ) 74 | 75 | 76 | # Metadados para o título 77 | tipo_crime <- unique(dados$evento) 78 | localidade <- paste0(unique(dados$municipio), " - ", unique(dados$uf)) 79 | conf_label <- paste0("Intervalo de confiança (", level, "%)") 80 | 81 | 82 | p <- ggplot2::ggplot(df_plot, ggplot2::aes(x = date)) + 83 | ggplot2::geom_line(ggplot2::aes(y = value, color = "Valor real (observado)"), linewidth = 0.9, na.rm = TRUE) + 84 | ggplot2::geom_line(ggplot2::aes(y = forecast, color = "Valor previsto"), linetype = "dashed", linewidth = 1.2, na.rm = TRUE) + 85 | ggplot2::geom_ribbon(ggplot2::aes(ymin = lower, ymax = upper, fill = conf_label), alpha = 0.25, na.rm = TRUE) + 86 | ggplot2::labs( 87 | title = paste0(tipo_crime), 88 | subtitle = paste0(localidade), 89 | y = "Quantidade", 90 | x = "", 91 | color = "", 92 | fill = "" 93 | ) + 94 | ggplot2::scale_color_manual(values = c("Valor real (observado)" = "#1B9E77", "Valor previsto" = "#D95F02")) + 95 | ggplot2::scale_fill_manual(values = setNames("#7570B3", conf_label)) + 96 | ggplot2::scale_x_date(date_labels = "%b %Y", date_breaks = "6 months") + 97 | ggplot2::theme_minimal(base_size = 14) + 98 | ggplot2::theme( 99 | legend.position = "bottom", 100 | axis.text.x = ggplot2::element_text(angle = 45, hjust = 1) 101 | ) 102 | 103 | print(p) 104 | 105 | return(list(model = model, forecast = fcast, plot = p, data = df_plot)) 106 | 107 | } 108 | 109 | # Evitar notas no R CMD check sobre variáveis do ggplot2 110 | if(getRversion() >= "2.15.1") utils::globalVariables(c( 111 | "value", "forecast", "lower", "upper" 112 | )) 113 | -------------------------------------------------------------------------------- /vignettes/br_crime_predict.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Fazendo Previsões com o BrazilCrime" 3 | author: | 4 | Giovanni Vargette, Igor Laltuf, Marcelo Justus 5 | output: 6 | bookdown::pdf_document2: 7 | toc: true 8 | toc_depth: 2 9 | number_sections: true 10 | latex_engine: xelatex 11 | fig_caption: true 12 | keep_tex: true 13 | margin_top: 2.5cm 14 | margin_bottom: 2.5cm 15 | margin_left: 2.5cm 16 | margin_right: 2.5cm 17 | header-includes: 18 | - \usepackage{indentfirst} 19 | - \setlength{\parindent}{1.5em} 20 | - \usepackage{fontspec} 21 | - \usepackage{polyglossia} 22 | - \usepackage{fvextra} 23 | - \usepackage{booktabs} 24 | - \usepackage{threeparttable} 25 | - \usepackage{multirow} 26 | - \usepackage{float} 27 | - \DefineVerbatimEnvironment{Highlighting}{Verbatim}{breaklines=true,fontsize=\small,commandchars=\\\{\}} 28 | vignette: > 29 | %\VignetteIndexEntry{Fazendo Previsões com o BrazilCrime} 30 | %\VignetteEngine{knitr::rmarkdown} 31 | %\VignetteEncoding{UTF-8} 32 | --- 33 | 34 | 35 | ```{r setup, include=FALSE} 36 | #library(BrazilCrime) 37 | #library(forecast) 38 | #library(ggplot2) 39 | #library(lubridate) 40 | #library(bookdown) 41 | 42 | knitr::opts_chunk$set(collapse = TRUE, comment = "#>") 43 | ``` 44 | 45 | # Introdução 46 | 47 | A função br_crime_predict() do pacote BrazilCrime permite gerar previsões de séries temporais criminais com base em modelos estatísticos robustos. É especialmente útil para análises de tendências futuras em ocorrências ou vítimas de crimes, sendo compatível com os dados obtidos via get_sinesp_vde_data(). 48 | 49 | A função utiliza modelos ARIMA e exponenciais suavizados para prever os valores futuros de forma automatizada, exibindo os resultados com gráficos claros e de fácil interpretação. 50 | 51 | # Sintaxe 52 | 53 | br_crime_predict(dados, ts_col="total", log = TRUE,freq = "monthly",h = 12,level = 95) 54 | 55 | ## Argumentos 56 | 57 | -dados: Data_frame que contém as informações a serem utilizdas. 58 | 59 | -ts_col: Nome da variável que será utilizada na previsão (Por exemplo: "total", "total_vitima"). 60 | 61 | -log: Lógico. Se TRUE, aplica transformação logarítmica nos dados antes da modelagem. Útil para séries com variância crescente. 62 | 63 | -freq: Granularidade dos dados, mensal ("monthly"), ou se estão agrupados anualmente ("yearly). 64 | 65 | -h: Número de períodos futuros a serem previstos (padrão: 12). 66 | 67 | -level: Nível de confiança que será utilizado na previsão. Padrão 95%. 68 | 69 | # Exemplo de Uso 70 | 71 | ```{r exemplo 1, tidy=TRUE, out.width='\\textwidth', fig.width=6, fig.height=4, results='asis'} 72 | dados <- BrazilCrime::get_sinesp_vde_data( 73 | state = "PE", 74 | city = "Recife", 75 | typology = "Homicídio doloso", 76 | category = "vitimas", 77 | granularity = "month", 78 | year = 2015:2023 79 | ) 80 | 81 | # Criar coluna de data (YYYY-MM) 82 | dados <- dados|> 83 | dplyr::mutate(data = lubridate::ymd(paste0(ano, "-", mes, "-01"))) |> 84 | dplyr::arrange(data) 85 | 86 | # Rodar previsão 87 | BrazilCrime::br_crime_predict(dados = dados,ts_col = "total_vitima", log = TRUE) 88 | ``` 89 | 90 | # Interpretação 91 | 92 | O gráfico gerado inclui: 93 | 94 | A série histórica original 95 | 96 | A previsão para os próximos steps_ahead meses 97 | 98 | Intervalos de confiança para as estimativas 99 | 100 | Indicação visual das transformações (caso o log = TRUE tenha sido ativado) 101 | 102 | # Considerações 103 | 104 | O desempenho do modelo pode variar de acordo com o comportamento da série (sazonalidade, tendência, etc.). 105 | 106 | É possível customizar os resultados combinando br_crime_predict() com filtros da função get_sinesp_vde_data() para diferentes cidades, anos ou tipologias. 107 | 108 | # Conclusão 109 | 110 | A função br_crime_predict() é uma ferramenta poderosa para análises exploratórias e preditivas de dados criminais. Seu uso, aliado às outras funções do pacote BrazilCrime, permite compreender padrões históricos e antecipar possíveis tendências com base em dados oficiais. 111 | 112 | 113 | \begin{thebibliography}{9} 114 | 115 | \bibitem{brazilcrime} 116 | Vargette, G., Laltuf, I., Justus, M. 117 | \textit{BrazilCrime: Interface to Brazilian Crime Data}. 118 | CRAN - Comprehensive R Archive Network. 119 | Disponível em: \url{https://CRAN.R-project.org/package=BrazilCrime} 120 | 121 | \bibitem{forecast} 122 | Hyndman, R. J., Athanasopoulos, G. (2021). 123 | \textit{Forecasting: Principles and Practice}. 124 | Disponível em: \url{https://otexts.com/fpp3/} 125 | 126 | \bibitem{lubridate} 127 | Grolemund, G., Wickham, H. (2011). 128 | \textit{Dates and Times Made Easy with lubridate}. 129 | \url{https://lubridate.tidyverse.org} 130 | 131 | \end{thebibliography} 132 | 133 | 134 | 135 | 136 | -------------------------------------------------------------------------------- /data-raw/base_sinesp_vde.R: -------------------------------------------------------------------------------- 1 | library(openxlsx) 2 | library(dplyr) 3 | library(readxl) 4 | library(usethis) 5 | 6 | options(timeout = 500) 7 | devtools::load_all() 8 | 9 | # Dados anteriores 10 | tabela_anterior <- get_sinesp_vde_data() 11 | quantidade_linhas_anterior <- nrow(tabela_anterior) 12 | 13 | current_year <- as.numeric(format(Sys.Date(), "%Y")) 14 | anos <- 2015:current_year 15 | 16 | base_url <- "https://www.gov.br/mj/pt-br/assuntos/sua-seguranca/seguranca-publica/estatistica/download/dnsp-base-de-dados/" 17 | 18 | # Função que monta o link correto 19 | montar_link <- function(ano) { 20 | if (ano == 2017) { 21 | return(paste0(base_url, "bancovde-2017.xlsx/@@download/file")) 22 | } else { 23 | return(paste0(base_url, "bancovde-", ano, ".xlsx/@@download/file")) 24 | } 25 | } 26 | 27 | # Função que baixa com retentativas 28 | baixar_arquivo <- function(ano) { 29 | link <- montar_link(ano) 30 | destfile <- paste0("data-raw/raw-sinesp-vde-data/bancovde-", ano, ".xlsx") 31 | dir.create(dirname(destfile), recursive = TRUE, showWarnings = FALSE) 32 | 33 | tentativas <- 0 34 | max_tentativas <- 3 35 | 36 | repeat { 37 | tentativas <- tentativas + 1 38 | cat("Baixando ano", ano, "- tentativa", tentativas, "\n") 39 | resultado <- tryCatch({ 40 | download.file(link, destfile, mode = "wb", quiet = TRUE) 41 | if (file.exists(destfile) && file.info(destfile)$size > 10000) { 42 | return(destfile) 43 | } else { 44 | stop("Arquivo baixado vazio ou corrompido.") 45 | } 46 | }, error = function(e) { 47 | message("Erro ao baixar ", ano, ": ", e$message) 48 | return(NULL) 49 | }) 50 | 51 | if (!is.null(resultado)) { 52 | return(destfile) 53 | } 54 | 55 | if (tentativas >= max_tentativas) { 56 | writeLines(paste("Falha ao baixar o ano", ano), "data-raw/log_status.txt") 57 | stop("Não foi possível baixar os dados do ano ", ano) 58 | } 59 | 60 | Sys.sleep(5) 61 | } 62 | } 63 | 64 | # Processa arquivo 65 | processar_dados <- function(destfile, ano) { 66 | df <- read_xlsx(destfile, guess_max = 10000) %>% 67 | mutate( 68 | data = as.Date(data_referencia, origin = "1899-12-30"), 69 | mes = format(data, "%m"), 70 | ano = ano 71 | ) 72 | return(df) 73 | } 74 | 75 | # Loop de anos 76 | lista_dfs <- lapply(anos, function(ano) { 77 | destfile <- baixar_arquivo(ano) 78 | if (!is.null(destfile)) processar_dados(destfile, ano) else NULL 79 | }) 80 | 81 | # Unir e classificar 82 | dados_unificados <- bind_rows(lista_dfs) 83 | 84 | sinesp_vde_data <- dados_unificados %>% 85 | mutate( 86 | categoria = case_when( 87 | evento %in% c("Apreensão de Cocaína", "Apreensão de Maconha", "Tráfico de drogas") ~ "drogas", 88 | evento %in% c("Arma de Fogo Apreendida") ~ "arma de fogo", 89 | evento %in% c("Feminicídio", "Homicídio doloso", "Lesão corporal seguida de morte", 90 | "Morte no trânsito ou em decorrência dele (exceto homicídio doloso)", 91 | "Mortes a esclarecer (sem indício de crime)", "Roubo seguido de morte (latrocínio)", 92 | "Suicídio", "Tentativa de homicídio", "Estupro", 93 | "Morte por intervenção de Agente do Estado","Tentativa de feminicídio") ~ "vitimas", 94 | evento %in% c("Furto de veículo", "Roubo a instituição financeira", "Roubo de carga", 95 | "Roubo de veículo") ~ "ocorrencias", 96 | evento %in% c("Pessoa Desaparecida", "Pessoa Localizada") ~ "desaparecidos/localizados", 97 | evento == "Mandado de prisão cumprido" ~ "mandado de prisao cumprido", 98 | evento %in% c("Morte de Agente do Estado", "Suicídio de Agente do Estado") ~ "profissionais de seguranca", 99 | evento %in% c("Atendimento pré-hospitalar", "Busca e salvamento", 100 | "Combate a incêndios", "Emissão de Alvarás de licença", "Realização de vistorias") ~ "bombeiros", 101 | TRUE ~ NA_character_ 102 | ) 103 | ) %>% 104 | select(uf, municipio, ano, mes, categoria, evento, agente, arma, faixa_etaria, 105 | feminino, masculino, nao_informado, total, total_peso, total_vitima) %>% 106 | arrange(uf, municipio, ano, mes, categoria, evento) 107 | 108 | # Salva apenas se há novos dados 109 | quantidade_linhas_atual <- nrow(sinesp_vde_data) 110 | 111 | if (quantidade_linhas_atual > quantidade_linhas_anterior) { 112 | usethis::use_data(sinesp_vde_data, 113 | compress = "xz", internal = TRUE, overwrite = TRUE) 114 | writeLines("Existem novos dados no SINESP VDE", "data-raw/log_status.txt") 115 | } else { 116 | writeLines("Os dados permanecem os mesmos", "data-raw/log_status.txt") 117 | } 118 | 119 | # Limpa ambiente 120 | rm(dados_unificados, tabela_anterior, anos, quantidade_linhas_anterior, 121 | quantidade_linhas_atual, current_year, base_url) 122 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # BrazilCrime 2 | 3 | 4 | [![NPM](https://img.shields.io/npm/l/react)](https://github.com/GiovanniVargette/BrazilCrime/blob/master/LICENSE) 5 | [![CRAN_Status_Badge](https://www.r-pkg.org/badges/version/BrazilCrime)](https://cran.r-project.org/package=BrazilCrime) 6 | [![CRAN_Download_Badge](https://cranlogs.r-pkg.org/badges/BrazilCrime)](https://CRAN.R-project.org/package=BrazilCrime) 7 | [![CRAN_Download_Badge](https://cranlogs.r-pkg.org/badges/grand-total/BrazilCrime)](https://CRAN.R-project.org/package=BrazilCrime) 8 | 9 | 10 | 11 | ## Roadmap de desenvolvimento 12 | 13 | - [X] Inclusão de shapes dos estados e argumento booleano para retornar dados espacializados; 14 | 15 | - [X] Adicionar argumento booleano para retornar o formato da tabela diferente com o tidyr; 16 | 17 | - [X] Inclusão de argumento booleano para retornar o número de ocorrências a cada 100 mil habitantes (dados de projeções mensais provenientes das [projeções](https://www.ibge.gov.br/estatisticas/sociais/populacao/9109-projecao-da-populacao.html?=&t=downloads) do IBGE); 18 | 19 | - [X] Adicionar testes para as funções; 20 | 21 | - [X] Adição da função que coleta os dados divulgados na plataforma [gov.br](https://www.gov.br/mj/pt-br/assuntos/sua-seguranca/seguranca-publica/estatistica/dados-nacionais-1/base-de-dados-e-notas-metodologicas-dos-gestores-estaduais-sinesp-vde-2022-e-2023) disponibilizados pelo Ministério da Justiça (Sinesp-VDE); 22 | 23 | - [X] Subir versão inicial para o CRAN; 24 | 25 | - [ ] Incluir dados populacionais anuais por município e interpolar dados por mês para o argumento relative_values da função get_sinesp_vde_data; e 26 | 27 | - [ ] Adicionar microdados do SUS com estatísticas sobre violência (agressões). 28 | 29 | 30 | ## Sobre o projeto 31 | 32 | A principal função do pacote BrazilCrime é disponibilizar de maneira acessível os dados sobre criminalidade e violência do Brasil, através da linguagem R. 33 | 34 | Para isso coleta-se as informações divulgadas pelo Sistema Nacional de Informações de Segurança Pública (Sinesp), órgao do Ministério da Justiça e Segurança Pública, esses dados são organizados em um data frame e disponibilizados ao usuário. 35 | 36 | Nessa primeira versão, temos disponível dados a partir de janeiro de 2015 até dezembro de 2022, em estratificação por unidade federativa, para as seguintes tipologias criminais: Estupro, Furto de Veículo, Homicídio Doloso, Lesão Corporal Seguida de Morte, Roubo a Insituição Financeira, Roubo de Carga, Roubo de Veículo, Roubo Seguido de Morte (Latrocínio) e Tentativa de Homicídio. 37 | 38 | 39 | 40 | # Instalação do Pacote 41 | 42 | Versão oficial no CRAN: 43 | 44 | ```r 45 | install.packages("BrazilCrime") 46 | library(BrazilCrime) 47 | ``` 48 | 49 | Versão de desenvolvimento: 50 | 51 | ```r 52 | install.packages("devtools") 53 | devtools::install_github("GiovanniVargette/BrazilCrime") 54 | library(BrazilCrime) 55 | ``` 56 | 57 | 58 | # Exemplos de uso das funções 59 | 60 | Baixar todos os dados do SINESP entre 2015 e 2022 com granularidade mensal. 61 | 62 | ```r 63 | dados <- get_sinesp_data() 64 | ``` 65 | 66 | Baixar todos os dados do SINESP entre 2015 e 2022 com granularidade anual. 67 | 68 | ```r 69 | dados <- get_sinesp_data(granularity = 'year') 70 | ``` 71 | 72 | Baixar todos os dados do SINESP de 2018 e 2019 sobre homicídio doloso para os 73 | estados de São Paulo, Rio de Janeiro e Minas Gerais com granularidade mensal. 74 | 75 | ```r 76 | dados <- get_sinesp_data(state = c('RJ', 'SP', 'MG'), 77 | typology = 'Homicídio doloso', 78 | year = c(2018, 2019)) 79 | ``` 80 | 81 | #### Exemplo 1: Baixar os dados dos estados do Sul do Brasil sobre roubo de veículos para o ano de 2022 com granularidade anual e com os vetores espaciais das UFs. 82 | 83 | ```r 84 | data_sul <- get_sinesp_data(state = c('PR','SC','RS'), 85 | typology = 'Roubo de veículo', 86 | year = 2022, 87 | geom = T, 88 | granularity = 'year') 89 | 90 | # criar o mapa 91 | library(ggplot2) 92 | ggplot(data = data_sul) + 93 | geom_sf(aes(fill = ocorrencias)) + 94 | theme_minimal() + 95 | labs(title = "Mapa de Ocorrências", 96 | subtitle = "Visualização espacial das ocorrências", 97 | fill = "Qtd de ocorrências") 98 | ``` 99 | 100 | 101 | 102 | #### Exemplo 2: Taxa mensal de roubo de carga ocorridos em SP de 2015 a 2022 103 | 104 | ``` 105 | txroub_carg_SP_mensal_ts <- get_sinesp_data(state = 'sp', 106 | typology = 'roubo de carga', 107 | granularity = 'month', 108 | relative_values = TRUE) 109 | 110 | names(txroub_carg_SP_mensal_ts) 111 | 112 | 113 | # Transformar para objeto ts (time series) 114 | txroub_carg_SP_mensal_ts <- ts(txroub_carg_SP_mensal_ts[,8], 115 | start = c(1, 2015), 116 | frequency = 12) 117 | 118 | # Estimando um modelo ARIMA pelo auto.arima 119 | (mod_auto <- auto.arima(txroub_carg_SP_mensal_ts, 120 | lambda = 0, # transf. log 121 | stepwise = TRUE, 122 | trace = TRUE, 123 | approximation = FALSE, 124 | allowdrift = TRUE, 125 | allowmean = TRUE, 126 | test = "kpss", 127 | ic = c("bic"))) 128 | 129 | # Análise visual dos resíduos 130 | par(mfrow=c(2,2)) 131 | plot(mod_auto$residuals, main="Resíduos", col=2) 132 | Acf(mod_auto$residuals, main="Resíduos", col=4) 133 | Acf((mod_auto$residuals)^2, main="Resíduos ao quadrado", col=4) 134 | plot(density(mod_auto$residuals, 135 | kernel = c("gaussian")), 136 | main="Resíduos", col=6) 137 | 138 | 139 | # Testes formais nos resíduos 140 | 141 | # Autocorrelação 142 | Box.test(mod_auto$residuals, 143 | lag=4, 144 | type="Ljung-Box", 145 | fitdf=2) 146 | 147 | Box.test(mod_auto$residuals, 148 | lag=8, 149 | type="Ljung-Box", 150 | fitdf=2) 151 | 152 | Box.test(mod_auto$residuals, 153 | lag=12, 154 | type="Ljung-Box", 155 | fitdf=2) 156 | 157 | # Heterocedasticidade condicional 158 | ArchTest(mod_auto$residuals, lags=4) 159 | ArchTest(mod_auto$residuals, lags=8) 160 | ArchTest(mod_auto$residuals, lags=12) 161 | 162 | # Normalidade 163 | shapiro.test(mod_auto$residuals) 164 | 165 | # Previsões 166 | forecast(mod_auto, h=24, level=95) 167 | 168 | autoplot(forecast(mod_auto, h=24, level=95)) 169 | ``` 170 | 171 | 172 | 173 | 174 | 175 | #### Exemplo 3: Roubo de carga a cada 100 mil habitantes por UF em 2022 176 | ``` 177 | q <- get_sinesp_data( 178 | typology = 'roubo de carga', 179 | granularity = 'year', 180 | year = 2022, 181 | relative_values = TRUE, 182 | geom = TRUE) 183 | 184 | ggplot(data = q) + 185 | geom_sf(aes(fill = ocorrencias_100k_hab), color = 'white') + 186 | scale_fill_viridis_c(option = "plasma", na.value = "white", name = NULL) + 187 | labs( 188 | title = "Roubos de Carga por 100 mil Habitantes em 2022", 189 | fill = "Ocorrências por 100k Habitantes" 190 | ) + 191 | theme_minimal() + 192 | theme( 193 | legend.position = "bottom", 194 | legend.direction = "horizontal", 195 | legend.title = element_blank(), 196 | panel.grid = element_blank(), 197 | plot.title = element_text(hjust = 0.5) 198 | ) 199 | ``` 200 | 201 | 202 | 203 | # Agradecimentos 204 | 205 | Marcelo Justus agradece ao CNPq pela Bolsa de Produtividade em Pesquisa (processo nº 312685/2021-1), que viabilizou a realização deste trabalho. Giovanni agradece ao CNPq pelas Bolsas de Iniciação Científica recebidas de 2023 a 2025, fundamentais para sua participação neste projeto. 206 | 207 | # Citação 208 | 209 | Para citar em trabalhos utilize: 210 | 211 | ```bash 212 | citation("BrazilCrime) 213 | 214 | #To cite package ‘BrazilCrime’ in publications use: 215 | 216 | # Vargette G, Justus M, Laltuf I (2024). _BrazilCrime: Crime data from Brazil_. R 217 | # package version 0.0.2, . 218 | 219 | #A BibTeX entry for LaTeX users is 220 | 221 | # @Manual{, 222 | # title = {BrazilCrime: Crime data from Brazil}, 223 | # author = {Giovanni Vargette, Marcelo Justus and Igor Laltuf}, 224 | # year = {2024}, 225 | # note = {R package version 0.0.3}, 226 | # url = {https://github.com/GiovanniVargette/BrazilCrime}, 227 | # } 228 | 229 | ``` 230 | -------------------------------------------------------------------------------- /vignettes/acess_dados_criminais_vde.Rmd: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Acessando dados criminais com BrazilCrime" 3 | author: | 4 | Giovanni Vargette, Igor Laltuf, Marcelo Justus 5 | output: 6 | bookdown::pdf_document2: 7 | toc: true 8 | toc_depth: 2 9 | number_sections: true 10 | latex_engine: xelatex 11 | fig_caption: true 12 | keep_tex: true 13 | margin_top: 2.5cm 14 | margin_bottom: 2.5cm 15 | margin_left: 2.5cm 16 | margin_right: 2.5cm 17 | header-includes: 18 | - \usepackage{indentfirst} 19 | - \setlength{\parindent}{1.5em} 20 | - \usepackage{fontspec} 21 | - \usepackage{polyglossia} 22 | - \usepackage{fvextra} 23 | - \usepackage{booktabs} 24 | - \usepackage{threeparttable} 25 | - \usepackage{multirow} 26 | - \usepackage{float} 27 | - \DefineVerbatimEnvironment{Highlighting}{Verbatim}{breaklines=true,fontsize=\small,commandchars=\\\{\}} 28 | vignette: > 29 | %\VignetteIndexEntry{Acessando dados criminais com BrazilCrime} 30 | %\VignetteEngine{knitr::rmarkdown} 31 | %\VignetteEncoding{UTF-8} 32 | --- 33 | 34 | 35 | 36 | ```{r setup, include=FALSE} 37 | #library(BrazilCrime) 38 | #library(ggplot2) 39 | #library(kableExtra) 40 | knitr::opts_chunk$set(collapse = TRUE, comment = "#>") 41 | ``` 42 | 43 | # Introdução 44 | 45 | O pacote BrazilCrime permite acessar dados públicos de segurança do sistema SINESP/VDE com filtros por localidade, tipologia criminal, categoria e período. 46 | 47 | A função central, get_sinesp_vde_data(), permite obter dados por UF, município, categoria (arma de fogo, bombeiros, desaparecidos/localizados, drogas, mandado de prisão cumprido, ocorrencias, profissionais de segurança e vitimas), para 28 tipologias de evento (Apreensão de Cocaína, Apreensão de Maconha, Arma de Fogo Apreendida, Atendimento pré-hospitalar, Busca e salvamento, Combate a incêndios, Emissão de Alvarás de licença, Estupro, Feminicídio, Homicídio doloso, Lesão corporal seguida de morte, Mandado de prisão cumprido, Morte de Agente do Estado, Morte no trânsito ou em decorrência dele (exceto homicídio doloso), Morte por intervenção de Agente do Estado, Mortes a esclarecer (sem indício de crime), Pessoa Desaparecida, Pessoa Localizada, Realização de vistorias, Roubo a instituição financeira, Roubo de carga, Roubo de veículo, Roubo seguido de morte (latrocínio), Suicídio, Suicídio de Agente do Estado, Tentativa de homicídio, Tráfico de drogas) com granularidade mensal ou anual. 48 | 49 | 50 | # Exemplos de Uso 51 | 52 | ## Exemplo 1 - Visualização simples 53 | 54 | ```{r exemplo 1, tidy=TRUE, out.width='\\textwidth', fig.width=6, fig.height=4, results='asis'} 55 | dados <- BrazilCrime::get_sinesp_vde_data() 56 | 57 | kableExtra::kable(head(dados), format = "latex", booktabs = TRUE, caption = "Visualização dos primeiros registros") |> 58 | kableExtra::kable_styling(latex_options = c("scale_down", "hold_position")) 59 | ``` 60 | 61 | ## Exemplo 2 - Filtrar por Estado, cidade e tipologia 62 | ```{r exemplo2, tidy=TRUE, out.width='\\textwidth', fig.width=6, fig.height=4, results='asis'} 63 | recife <- BrazilCrime::get_sinesp_vde_data( 64 | state = "PE", 65 | city = "Recife", 66 | typology = "Homicídio doloso", 67 | year = 2020:2022 68 | ) 69 | 70 | kableExtra::kable(head(recife), format = "latex", booktabs = TRUE, caption = "Visualização dos primeiros registros") |> 71 | kableExtra::kable_styling(latex_options = c("scale_down", "hold_position")) 72 | ``` 73 | 74 | ## Exemplo 3 - Dados agregados por ano, para Estado e categoria específica 75 | ```{r exemplo3, tidy=TRUE, out.width='\\textwidth', fig.width=6, fig.height=4, results='asis'} 76 | sp_anuais <- BrazilCrime::get_sinesp_vde_data( 77 | state = "SP", 78 | category = "ocorrencias", 79 | granularity = "year" 80 | ) 81 | 82 | 83 | kableExtra::kable(head(sp_anuais), format = "latex", booktabs = TRUE, caption = "Visualização dos primeiros registros") |> 84 | kableExtra::kable_styling(latex_options = c("scale_down", "hold_position")) 85 | ``` 86 | 87 | ## Exemplo 4 - Visualização rápida 88 | ```{r exemplo4, tidy=TRUE, out.width='\\textwidth', fig.width=6, fig.height=4, results='asis'} 89 | #library(ggplot2) 90 | 91 | ggplot2::ggplot(sp_anuais, ggplot2::aes(x = ano, y = total)) + 92 | ggplot2::geom_line(color = "#0072B2", size = 1.2) + 93 | ggplot2::geom_point(color = "#D55E00", size = 2) + 94 | ggplot2::facet_wrap(~evento) + 95 | ggplot2::labs( 96 | title = "Evolução anual de ocorrências no Estado de SP", 97 | y = "Total de ocorrências", 98 | x = "Ano" 99 | ) + 100 | ggplot2::theme_minimal(base_size = 12) + 101 | ggplot2::theme( 102 | plot.title = ggplot2::element_text(face = "bold", size = 14), 103 | axis.text.x = ggplot2::element_text(angle = 45, hjust = 1) 104 | ) 105 | ``` 106 | 107 | ## Exemplo 5 - Visualização de dados com vítimas 108 | ```{r exemplo5, tidy=TRUE, out.width='\\textwidth', fig.width=6, fig.height=4, results='asis'} 109 | #library(ggplot2) 110 | 111 | sp_anuais_vit <- BrazilCrime::get_sinesp_vde_data( 112 | state = "SP", 113 | city = "SÃO PAULO", 114 | category = "vitimas", 115 | granularity = "year" 116 | ) 117 | 118 | # Quebrar nomes longos nos títulos dos facetes 119 | sp_anuais_vit$evento <- stringr::str_wrap(sp_anuais_vit$evento, width = 20) 120 | 121 | ggplot2::ggplot(sp_anuais_vit, ggplot2::aes(x = ano, y = total_vitima)) + 122 | ggplot2::geom_line(color = "#0072B2", size = 1.2) + 123 | ggplot2::geom_point(color = "#D55E00", size = 2) + 124 | ggplot2::facet_wrap(~evento) + 125 | ggplot2::labs( 126 | title = "Evolução anual de vítimas na cidade de SP", 127 | y = "Total de vítimas", 128 | x = "Ano" 129 | ) + 130 | ggplot2::theme_minimal(base_size = 12) + 131 | ggplot2::theme( 132 | plot.title = ggplot2::element_text(face = "bold", size = 14), 133 | axis.text.x = ggplot2::element_text(angle = 45, hjust = 1), 134 | strip.text = ggplot2::element_text(size = 8)) 135 | ``` 136 | 137 | ## Exemplo 6 - Buscando tendências com o argumento geom_smooth em ggplot 138 | ```{r exemplo6,tidy=TRUE, out.width='\\textwidth', fig.width=6, fig.height=4, results='asis'} 139 | # Carregar dados 140 | dados_var <- BrazilCrime::get_sinesp_vde_data( 141 | state = "BA", 142 | typology = "Homicídio doloso", 143 | city = "Salvador", 144 | category = "vitimas", 145 | granularity = "month", 146 | year = 2015:2023) 147 | 148 | dados_var <- dados_var |> 149 | dplyr::mutate(data = as.Date(paste0(ano, "-", mes, "-01"))) 150 | 151 | 152 | # Carregar pacotes 153 | #library(ggplot2) 154 | 155 | # Criar gráfico com smoothing 156 | ggplot2::ggplot(dados_var, ggplot2::aes(x = data)) + 157 | ggplot2::geom_line(ggplot2::aes(y = total_vitima, color = "Valores mensais"), size = 0.8) + 158 | ggplot2::geom_smooth( 159 | ggplot2::aes(y = total_vitima, color = "Tendência"), 160 | method = "loess", 161 | se = FALSE, 162 | size = 1.2, 163 | span = 0.3 164 | ) + 165 | ggplot2::scale_color_manual( 166 | name = "Série Temporal", 167 | values = c("Valores mensais" = "#0072B2", "Tendência" = "#D55E00") 168 | ) + 169 | ggplot2::labs( 170 | title = "Tendência de homicídios dolosos em Salvador - BA (2015–2023)", 171 | x = "Data", 172 | y = "Total de Vítimas" 173 | ) + 174 | ggplot2::theme_minimal(base_size = 12) + 175 | ggplot2::theme( 176 | plot.title = ggplot2::element_text(face = "bold", size = 10, hjust = 0.5), 177 | axis.text.x = ggplot2::element_text(angle = 45, hjust = 1), 178 | panel.grid.minor = ggplot2::element_blank(), 179 | legend.position = "top", 180 | legend.direction = "horizontal", 181 | legend.box = "horizontal", 182 | legend.title = ggplot2::element_text(size = 9, face = "bold"), 183 | legend.text = ggplot2::element_text(size = 9) 184 | ) 185 | 186 | 187 | ``` 188 | 189 | ## Exemplo 7 - Análise de correlação 190 | ```{r exemplo7,tidy=TRUE, out.width='\\textwidth', fig.width=6, fig.height=4, results='asis'} 191 | # Pacotes necessários 192 | #library(BrazilCrime) 193 | #library(tidyverse) 194 | #library(ggcorrplot) 195 | 196 | # Buscar dados para SP em 2022 (cross-section municipal) 197 | dados_cross <- BrazilCrime::get_sinesp_vde_data( 198 | state = "SP", 199 | granularity = "year", 200 | year = 2022, 201 | category = "vitimas" 202 | ) 203 | 204 | # Selecionar algumas tipologias comuns 205 | tipos_desejados <- c("Feminicídio", "Homicídio doloso", "Suicídio", 206 | "Lesão corporal seguida de morte") 207 | 208 | # Agrupar e pivotar os dados corretamente 209 | dados_filtrados <- dados_cross |> 210 | dplyr::filter(evento %in% tipos_desejados) |> 211 | dplyr::group_by(municipio, evento) |> 212 | dplyr::summarise(total_vitima = sum(total_vitima, na.rm = TRUE), .groups = "drop") |> 213 | tidyr::pivot_wider(names_from = evento, values_from = total_vitima) |> 214 | tidyr::drop_na() |> 215 | dplyr::mutate(across(-municipio, as.numeric)) 216 | 217 | # Calcular matriz de correlação 218 | matriz_cor <- cor(dados_filtrados[-1], method = "pearson") 219 | 220 | # Gerar gráfico de correlação 221 | ggcorrplot::ggcorrplot( 222 | matriz_cor, 223 | lab = TRUE, 224 | lab_size = 3, 225 | colors = c("#D73027", "white", "#1A9850"), 226 | outline.color = "gray80" 227 | ) + 228 | ggplot2::ggtitle("Correlação entre diferentes crimes em SP (2022)") + 229 | ggplot2::theme_minimal() + 230 | ggplot2::theme( 231 | plot.title = ggplot2::element_text(size = 14, hjust = 0.5), 232 | plot.margin = ggplot2::margin(t = 20, r = 10, b = 20, l = 10), 233 | axis.text.x = ggplot2::element_text(angle = 45, vjust = 1, hjust = 1) 234 | ) 235 | 236 | ``` 237 | --- 238 | 239 | 240 | 241 | \begin{thebibliography}{9} 242 | 243 | \bibitem{mjsp} 244 | Ministério da Justiça e Segurança Pública (MJSP). 245 | \textit{SINESP - Sistema Nacional de Informações de Segurança Pública}. 246 | Disponível em: \url{https://www.gov.br/mj/pt-br/assuntos/sua-seguranca/seguranca-publica/estatistica/dados-nacionais-1/base-de-dados-e-notas-metodologicas-dos-gestores-estaduais-sinesp-vde-2022-e-2023}. Acesso em: julho de 2025. 247 | 248 | \bibitem{brazilcrime} 249 | Vargette, G., Laltuf, I., Justus, M. (2024). 250 | \textit{BrazilCrime: Interface to Brazilian Crime Data}. 251 | CRAN - Comprehensive R Archive Network. 252 | Disponível em: \url{https://CRAN.R-project.org/package=BrazilCrime} 253 | 254 | \bibitem{ggplot2} 255 | Wickham, H. (2016). 256 | \textit{ggplot2: Elegant Graphics for Data Analysis}. 257 | Springer-Verlag New York. \url{https://ggplot2.tidyverse.org} 258 | 259 | \bibitem{ggcorrplot} 260 | Gu, Z., Eils, R., Schlesner, M. (2022). 261 | \textit{ggcorrplot: Visualization of a Correlation Matrix using ggplot2}. 262 | Disponível em: \url{https://cran.r-project.org/package=ggcorrplot} 263 | 264 | \bibitem{rbase} 265 | R Core Team (2024). 266 | \textit{R: A Language and Environment for Statistical Computing}. 267 | R Foundation for Statistical Computing, Vienna, Austria. 268 | \url{https://www.R-project.org/} 269 | 270 | \bibitem{kableextra} 271 | Zhu, H. (2021). 272 | \textit{kableExtra: Construct Complex Table with 'kable' and Pipe Syntax}. 273 | CRAN. \url{https://cran.r-project.org/package=kableExtra} 274 | 275 | \bibitem{dplyr} 276 | Wickham, H., François, R., Henry, L., Müller, K. (2019). 277 | \textit{dplyr: A Grammar of Data Manipulation}. 278 | \url{https://dplyr.tidyverse.org} 279 | 280 | \bibitem{tidyr} 281 | Wickham, H. (2023). 282 | \textit{tidyr: Tidy Messy Data}. 283 | \url{https://tidyr.tidyverse.org} 284 | 285 | \bibitem{stringr} 286 | Chang, W. (2023). 287 | \textit{stringr: Simple, Consistent Wrappers for Common String Operations}. 288 | \url{https://stringr.tidyverse.org} 289 | 290 | \end{thebibliography} 291 | --------------------------------------------------------------------------------