From ec729854a9b08bf9f741930aef9704063d8403c0 Mon Sep 17 00:00:00 2001 From: Daniel Herszenhut Date: Mon, 29 Jan 2024 13:43:10 -0300 Subject: [PATCH] primeira versao da padronizar_municipios() --- NAMESPACE | 1 + R/enderecopadrao.R | 2 +- R/padronizar_municipios.R | 97 +++++++++++++++++++++ _pkgdown.yml | 1 + man/padronizar_municipios.Rd | 49 +++++++++++ tests/testthat/test-padronizar_municipios.R | 25 ++++++ 6 files changed, 174 insertions(+), 1 deletion(-) create mode 100644 R/padronizar_municipios.R create mode 100644 man/padronizar_municipios.Rd create mode 100644 tests/testthat/test-padronizar_municipios.R diff --git a/NAMESPACE b/NAMESPACE index db7bc95..e1e4754 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -2,4 +2,5 @@ export(padronizar_ceps) export(padronizar_estados) +export(padronizar_municipios) export(padronizar_numeros) diff --git a/R/enderecopadrao.R b/R/enderecopadrao.R index b9ecfda..b2151e0 100644 --- a/R/enderecopadrao.R +++ b/R/enderecopadrao.R @@ -5,4 +5,4 @@ #' @keywords internal "_PACKAGE" -utils::globalVariables("codigos_estados") +utils::globalVariables(c("codigos_estados", "codigos_municipios")) diff --git a/R/padronizar_municipios.R b/R/padronizar_municipios.R new file mode 100644 index 0000000..75d47d7 --- /dev/null +++ b/R/padronizar_municipios.R @@ -0,0 +1,97 @@ +#' Padronizar municípios +#' +#' Padroniza um vetor de caracteres ou números representando municípios +#' brasileiros. Veja a seção *Detalhes* para mais informações sobre a +#' padronização. +#' +#' @param municipios Um vetor de caracteres ou números. Os municípios a serem +#' padronizados. +#' +#' @return Um vetor de caracteres com os municípios padronizados. +#' +#' @section Detalhes: +#' Operações realizadas durante a padronização: +#' +#' 1. conversão para caracter, se o input for numérico; +#' 2. remoção de espaços em branco antes e depois dos valores e remoção de +#' espaços em excesso entre palavras; +#' 3. conversão de caracteres para caixa alta; +#' 4. remoção de zeros à esquerda; +#' 5. busca, a partir do código numérico, do nome completo de cada município; +#' 6. caso a busca não tenha encontrado determinado valor, remoção de acentos e +#' caracteres não ASCII - esta etapa, de manipulação de strings, pode ser +#' incrementada para adequação futura a bases de dados com as quais as etapas +#' anteriores não resultem em valores padronizados. +#' +#' @examples +#' municipios <- c( +#' "3304557", "003304557", " 3304557 ", "RIO DE JANEIRO", "rio de janeiro", +#' "SÃO PAULO", +#' "", NA +#' ) +#' padronizar_municipios(municipios) +#' +#' municipios <- c(21, NA) +#' padronizar_municipios(municipios) +#' +#' @export +padronizar_municipios <- function(municipios) { + checkmate::assert( + checkmate::check_character(municipios), + checkmate::check_numeric(municipios), + combine = "or" + ) + + # alguns municipios podem vir vazios e devem permanecer vazios ao final. + # identificamos o indice dos municipios vazios para "reesvazia-los" ao final, + # ja que a sequencia de operacoes abaixo acabaria atribuindo um valor a eles + + indice_municipio_vazio <- which(municipios == "" | is.na(municipios)) + + if (is.numeric(municipios)) { + municipios_padrao <- formatC(municipios, format = "d") + } else { + municipios_padrao <- stringr::str_squish(municipios) + municipios_padrao <- toupper(municipios_padrao) + municipios_padrao <- stringr::str_replace_all( + municipios_padrao, + c("\\b0+(\\d+)\\b" = "\\1") + ) + } + + # em uma primeira etapa, fazemos uma busca dos nomes completos dos municipios + # a partir de seus códigos numericos. apos essa etapa, se ainda houver algum + # registro de valor diferente dos nomes completos padroes, fazemos uma serie + # de manipulacoes de string que tomam um pouco mais de tempo + + vetor_busca_com_cod <- codigos_municipios$nome_muni + names(vetor_busca_com_cod) <- codigos_municipios$codigo_muni + result_busca_com_cod <- vetor_busca_com_cod[municipios_padrao] + + municipios_padrao <- ifelse( + is.na(result_busca_com_cod), + municipios_padrao, + result_busca_com_cod + ) + names(municipios_padrao) <- NULL + + municipios_padrao[indice_municipio_vazio] <- "" + + municipio_nao_padrao <- !( + municipios_padrao %in% c(codigos_municipios$nome_muni, "") + ) + + if (any(municipio_nao_padrao)) { + municipios_padrao[municipio_nao_padrao] <- manipular_nome_muni( + municipios_padrao[municipio_nao_padrao] + ) + } + + return(municipios_padrao) +} + +manipular_nome_muni <- function(muni) { + muni <- stringi::stri_trans_general(muni, "Latin-ASCII") + + return(muni) +} diff --git a/_pkgdown.yml b/_pkgdown.yml index 3dcc488..995b13a 100644 --- a/_pkgdown.yml +++ b/_pkgdown.yml @@ -2,6 +2,7 @@ reference: - title: "Padronização de campos individuais" - contents: - padronizar_estados + - padronizar_municipios - padronizar_ceps - padronizar_numeros - title: "Tabelas de códigos" diff --git a/man/padronizar_municipios.Rd b/man/padronizar_municipios.Rd new file mode 100644 index 0000000..35836bb --- /dev/null +++ b/man/padronizar_municipios.Rd @@ -0,0 +1,49 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/padronizar_municipios.R +\name{padronizar_municipios} +\alias{padronizar_municipios} +\title{Padronizar municípios} +\usage{ +padronizar_municipios(municipios) +} +\arguments{ +\item{municipios}{Um vetor de caracteres ou números. Os municípios a serem +padronizados.} +} +\value{ +Um vetor de caracteres com os municípios padronizados. +} +\description{ +Padroniza um vetor de caracteres ou números representando municípios +brasileiros. Veja a seção \emph{Detalhes} para mais informações sobre a +padronização. +} +\section{Detalhes}{ + +Operações realizadas durante a padronização: +\enumerate{ +\item conversão para caracter, se o input for numérico; +\item remoção de espaços em branco antes e depois dos valores e remoção de +espaços em excesso entre palavras; +\item conversão de caracteres para caixa alta; +\item remoção de zeros à esquerda; +\item busca, a partir do código numérico, do nome completo de cada município; +\item caso a busca não tenha encontrado determinado valor, remoção de acentos e +caracteres não ASCII - esta etapa, de manipulação de strings, pode ser +incrementada para adequação futura a bases de dados com as quais as etapas +anteriores não resultem em valores padronizados. +} +} + +\examples{ +municipios <- c( + "3304557", "003304557", " 3304557 ", "RIO DE JANEIRO", "rio de janeiro", + "SÃO PAULO", + "", NA +) +padronizar_municipios(municipios) + +municipios <- c(21, NA) +padronizar_municipios(municipios) + +} diff --git a/tests/testthat/test-padronizar_municipios.R b/tests/testthat/test-padronizar_municipios.R new file mode 100644 index 0000000..5933227 --- /dev/null +++ b/tests/testthat/test-padronizar_municipios.R @@ -0,0 +1,25 @@ +test_that("da erro com inputs != de caracteres e municipios", { + expect_error(padronizar_municipios(as.factor(3304557))) +}) + +test_that("padroniza corretamente", { + expect_equal(padronizar_municipios("3304557"), "RIO DE JANEIRO") + expect_equal(padronizar_municipios("03304557"), "RIO DE JANEIRO") + expect_equal(padronizar_municipios(" 3304557 "), "RIO DE JANEIRO") + expect_equal(padronizar_municipios("rio de janeiro"), "RIO DE JANEIRO") + expect_equal(padronizar_municipios(NA_character_), "") + expect_equal(padronizar_municipios(""), "") + + expect_equal(padronizar_municipios(3304557), "RIO DE JANEIRO") + expect_equal(padronizar_municipios(NA_integer_), "") + expect_equal(padronizar_municipios(c(3304557, NA)), c("RIO DE JANEIRO", "")) + + # manipulacao de strings + expect_equal(padronizar_municipios("SÃO PAULO"), "SAO PAULO") +}) + +test_that("lida com vetores vazios corretamente", { + expect_equal(padronizar_municipios(character(0)), character(0)) + expect_equal(padronizar_municipios(integer(0)), character(0)) + expect_equal(padronizar_municipios(numeric(0)), character(0)) +})