Capítulo 4 Importando e exportando dados no R

4.1 Importando dados no R

Na realização de nossas tarefas, podemos nos deparar com dados em diversos formatos, como:

  • CSV - Comma-separated values;
  • TXT - Arquivo texto;
  • JSON - JavaScript Object Notation;
  • XML - eXtensible Markup Language;
  • TSV - Tab-separated values;
  • XLS e XLSX - Arquivos do MS Excel;
  • HTML - HyperText Markup Language;
  • PDF - Portable Document Format.

Além de lidar com todos os formatos citados, o R possui pacotes para leitura de arquivos gerados por softwares como Stata, SPSS e SAS, muito utilizados em aplicações estatísticas e análise de dados. Na verdade, existe uma infinidade de formatos que o R consegue importar. Esses são apenas os principais.

O R também consegue se conectar às mais diferentes bases de dados, como:

  • Microsoft SQL Server;
  • Oracle;
  • PostgreSQL;
  • Amazon Redshift;
  • Apache Hive;
  • Apache Impala;
  • Salesforce;
  • Teradata;
  • Google BigQuery.

No entanto, para o objetivo do nosso curso, vamos aprender a ler os arquivos nos formatos mais populares, além de descobrir algumas características dos pacotes e funções utilizadas.

4.1.1 Importando arquivos CSV

Os arquivos CSV são bastante utilizados para disponibilização de dados. É um formato bem antigo e que utiliza vírgulas para separação dos valores. No entanto, implementações mais sofisticadas utilizam aspas duplas (““) entorno do conteúdo e podem ter outro tipo de separador, como o ponto e vírgula (;).

Há pacotes muito bons para leitura de arquivos CSV como o readr, vroom, e o data.table. Também possuímos funções nativas do R como a read.csv() e a read.csv2().

Vamos iniciar lendo o nosso primeiro arquivo CSV utilizando a função nativa do R read.csv2() uma vez que o separador do nosso arquivo é “;” e não “,”. Antes de importarmos nossos dados, vamos executar o comando de ajuda da função citada (?read.csv2()).

Olhando a documentação da função read.csv2(), podemos constatar que há diversos argumentos com seus respectivos valores padrão. Os três pontos (…) nos argumentos indicam que os demais parâmetros são idênticos aos da função read.table() que também exibiremos a seguir.

read.csv2(file, header = TRUE, sep = ";", quote = "\"",
          dec = ",", fill = TRUE, comment.char = "", ...)

read.table(file, header = FALSE, sep = "", quote = "\"'",
           dec = ".", numerals = c("allow.loss", "warn.loss", "no.loss"),
           row.names, col.names, as.is = !stringsAsFactors,
           na.strings = "NA", colClasses = NA, nrows = -1,
           skip = 0, check.names = TRUE, fill = !blank.lines.skip,
           strip.white = FALSE, blank.lines.skip = TRUE,
           comment.char = "#",
           allowEscapes = FALSE, flush = FALSE,
           stringsAsFactors = FALSE,
           fileEncoding = "", encoding = "unknown", text, skipNul = FALSE)

Vamos iniciar tentando importar o arquivo com extensão *.csv que contém os dados da execução de receita do Governo do Estado da Paraíba em março de 20224. Apontaremos o argumento file = para onde se encontra o arquivo, no caso, dentro da pasta dados do nosso projeto. Feito isso podemos inspecionar os dados, tanto através do RStudio como executando a função str() ou head().

receitas <- read.csv2(file = "dados/receitas_execucao_exercicio_2022_mes_3.csv")

head(receitas)
##   EXERCICIO MES CODIGO_UNIDADE_GESTORA CODIGO_ITEM_RECEITA                                                                      NOME_ITEM_RECEITA
## 1      2022   3                 200001            11125101       Imposto sobre a Propriedade de Veiculos Automotores - Principal                 
## 2      2022   3                 200001            11125102       Imposto sobre a Propriedade de Veiculos Automotores - Multas e Juros de Mora    
## 3      2022   3                 200001            11125103       Imposto sobre a Propriedade de Veiculos Automotores - Divida Ativa              
## 4      2022   3                 200001            11125104 Imposto sobre a Propriedade de Ve\xedculos Automotores - D\xedvida Ativa - Multas e Ju
## 5      2022   3                 200001            11125201       Imposto sobre Transmissao Causa Mortis e Doacao de Bens e Direitos - Principal  
## 6      2022   3                 200001            11125202       Imp Transm Causa Mortis Doacao Bens Dir-Multas                                  
##   CODIGO_FONTE_RECURSO   VALOR_MES VALOR_ATE_MES CODIGO_CATEGORIA_RECEITA CODIGO_ORIGEM_RECEITA CODIGO_ESPECIE_RECEITA CODIGO_RUBRICA_RECEITA
## 1                50000 19829458.14   55808213.78                        1                     1                      1                      2
## 2                50000   548722.00    1767421.46                        1                     1                      1                      2
## 3                50000   321748.44     777826.40                        1                     1                      1                      2
## 4                50000   120575.44     297863.04                        1                     1                      1                      2
## 5                50000  4892179.82   14412503.82                        1                     1                      1                      2
## 6                50000   228255.86     675504.80                        1                     1                      1                      2
##   CODIGO_ALINEA_RECEITA CODIGO_SUBALINEA_RECEITA RECEITA_COVID
## 1                    51                        1         false
## 2                    51                        2         false
## 3                    51                        3         false
## 4                    51                        4         false
## 5                    52                        1         false
## 6                    52                        2         false

Após inspecionarmos os dados, temos dois problemas a serem resolvidos. O primeiro é a importação de variáveis numéricas como carácter (chr), o segundo é a codificação das variáveis em texto. É possível perceber que palavras acentuadas não estão sendo exibidas corretamente. Para nossa sorte, todos os dois são facilmente contornados por argumentos da função read.csv2().

O primeiro problema foi causado devido ao arquivo lido possuir . como separador decimal, enquanto a função possui por padrão a vírgula. O segundo problema foi devido à codificação em “Latin-1”. A maioria dos arquivos em língua portuguesa são codificados em “Latin-1” (ISO-8859-1) ou em UTF-8. Alterando os argumentos da função, já temos tais problemas tratados na hora da importação.

receitas <- read.csv2(file = "dados/receitas_execucao_exercicio_2022_mes_3.csv",
                      dec = ".", encoding = "latin1")

head(receitas)
##   EXERCICIO MES CODIGO_UNIDADE_GESTORA CODIGO_ITEM_RECEITA                                                                NOME_ITEM_RECEITA
## 1      2022   3                 200001            11125101 Imposto sobre a Propriedade de Veiculos Automotores - Principal                 
## 2      2022   3                 200001            11125102 Imposto sobre a Propriedade de Veiculos Automotores - Multas e Juros de Mora    
## 3      2022   3                 200001            11125103 Imposto sobre a Propriedade de Veiculos Automotores - Divida Ativa              
## 4      2022   3                 200001            11125104 Imposto sobre a Propriedade de Veículos Automotores - Dívida Ativa - Multas e Ju
## 5      2022   3                 200001            11125201 Imposto sobre Transmissao Causa Mortis e Doacao de Bens e Direitos - Principal  
## 6      2022   3                 200001            11125202 Imp Transm Causa Mortis Doacao Bens Dir-Multas                                  
##   CODIGO_FONTE_RECURSO  VALOR_MES VALOR_ATE_MES CODIGO_CATEGORIA_RECEITA CODIGO_ORIGEM_RECEITA CODIGO_ESPECIE_RECEITA CODIGO_RUBRICA_RECEITA
## 1                50000 19829458.1    55808213.8                        1                     1                      1                      2
## 2                50000   548722.0     1767421.5                        1                     1                      1                      2
## 3                50000   321748.4      777826.4                        1                     1                      1                      2
## 4                50000   120575.4      297863.0                        1                     1                      1                      2
## 5                50000  4892179.8    14412503.8                        1                     1                      1                      2
## 6                50000   228255.9      675504.8                        1                     1                      1                      2
##   CODIGO_ALINEA_RECEITA CODIGO_SUBALINEA_RECEITA RECEITA_COVID
## 1                    51                        1         false
## 2                    51                        2         false
## 3                    51                        3         false
## 4                    51                        4         false
## 5                    52                        1         false
## 6                    52                        2         false

Nota: É possível fazer o tratamento de tais problemas após a importação, mas como veremos também adiante, as funções de leitura que iremos tralhar já disponibilizam vários argumentos capazes de lidar com isso no momento da importação, algo que facilita bastante. Quanto mais conseguirmos deixamos os dados prontos para a análise desde a importação, melhor!

4.1.2 Importanto arquivos TXT

O processo de importação de arquivos texto é bastante similar ao já visto anteriormente com arquivos em CSV (item 4.1.1). Iremos utilizar a função nativa read.table() com argumentos idênticos ao do exemplo anterior, com exceção do header = TRUE. Isso ocorre devido à função utilizada trazer como padrão o valor header = FALSE. Como a primeira linha do arquivo contém informações do cabeçalho, devemos indicar isso no cabeçalho da função.

resumo_folha  <- read.table("dados/resumo_folha_exercicio_2022_mes_3.txt",
                            sep = ";", encoding = "latin1", header = TRUE)

str(resumo_folha)
## 'data.frame':    8491 obs. of  13 variables:
##  $ EXERCICIO         : int  2022 2022 2022 2022 2022 2022 2022 2022 2022 2022 ...
##  $ MES               : int  3 3 3 3 3 3 3 3 3 3 ...
##  $ QUADRO            : chr  "PENSIONISTAS" "INATIVOS" "INATIVOS" "INATIVOS" ...
##  $ PODER             : chr  "EXECUTIVO" "EXECUTIVO" "EXECUTIVO" "EXECUTIVO" ...
##  $ ADMINISTRACAO     : chr  "ADMINISTRAÇÃO DIRETA" "ADMINISTRAÇÃO DIRETA" "ADMINISTRAÇÃO DIRETA" "ADMINISTRAÇÃO DIRETA" ...
##  $ ORGAO             : chr  "PBPREV - PENSIONISTA          " "PBPREV - INATIVO              " "PBPREV - INATIVO              " "PBPREV - INATIVO              " ...
##  $ SECRETARIA        : chr  "PBPREV - PENSIONISTA          " "PBPREV - INATIVO              " "PBPREV - INATIVO              " "PBPREV - INATIVO              " ...
##  $ UNIDADE_TRABALHO  : chr  "PBPREV - PENSIONISTA" "PBPREV - INATIVO" "PBPREV - INATIVO" "PBPREV - INATIVO" ...
##  $ NOME_MUNICIPIO    : chr  "JOAO PESSOA" "JOAO PESSOA" "JOAO PESSOA" "JOAO PESSOA" ...
##  $ GRUPO             : chr  "PENSAO" "MAGISTERIO" "QUADRO ESPECIAL" "POLICIA MILITAR" ...
##  $ REGIME            : chr  "PENSIONISTA" "ESTATUTARIO INATIVO" "ESTATUTARIO INATIVO" "MILITAR REFORMADO" ...
##  $ QUANTIDADE        : int  6287 4996 2846 2267 1747 1706 1670 1475 1420 1321 ...
##  $ SOMA_SALARIO_BRUTO: num  30212177 18823501 4178284 13430012 7629876 ...

4.1.3 Importando arquivos do MS Excel

Para a importação de arquivos do MS Excel, utilizaremos o pacote readxl (Hadley Wickham e Bryan 2019), integrante do Tidyverse. O arquivo que iremos importar é o referente ao indicador de esforço do docente referente a 2021, disponibilizado pelo Instituto Nacional de Estudos e Pesquisas Educacionais Anísio Teixeira - INEP.

Vamos tentar ler o nosso arquivo sem alterar nenhum argumento da função read_xslx(). Feito isso, vamos observar como os dados foram importados.

library(readxl)
inep_esf_docente <- read_xlsx("dados/IED_BRASIL_REGIOES_UFS_2021.xlsx")
## New names:
## * `` -> ...1
## * `` -> ...3
## * `` -> ...4
## * `` -> ...5
## * `` -> ...6
## * ...
head(inep_esf_docente)
## # A tibble: 6 × 28
##   ...1    `Ministério da … ...3  ...4  ...5  ...6  ...7  ...8  ...9  ...10 ...11 ...12 ...13 ...14 ...15 ...16 ...17 ...18 ...19 ...20 ...21 ...22 ...23 ...24
##   <chr>   <chr>            <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr>
## 1 <NA>    Instituto Nacio… <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA> 
## 2 <NA>    <NA>             <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA> 
## 3 Percen… <NA>             <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA> 
## 4 Percen… <NA>             <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA> 
## 5 <NA>    <NA>             <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA> 
## 6 Ano     Unidade Geográf… Loca… Depe… Perc… <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA>  <NA> 
## # … with 4 more variables: ...25 <chr>, ...26 <chr>, ...27 <chr>, ...28 <chr>

Ao verificar o arquivo importado, podemos constatar que há uma série de problemas logo nas primeiras linhas. Isso ocorre devido ao fato do nosso arquivo importado possuir um cabeçalho, com diversas células mescladas (inspecione o arquivo pelo Excel), imagem e etc. Porém, inicialmente, este não é o único problema que podemos resolver já na importação. Os valores ausentes na planilha foram substituídos por “–” ao invés de serem células vazias.

Vamos tentar novamente importar nosso arquivo alterando os argumentos skip e na. O argumento skip indica a quantidade de linhas que queremos que a função ignore na importação. Nesse caso, identificamos que as dez primeiras linhas são de cabeçalho, logo, vamos ter skip = 10.

Por outro lado, devemos também indicar que “–” deve ser importado como NA, isso permitirá que as variáveis numéricas não sejam importadas incorretamente como texto (chr). Fazemos isso com na = "--". Vejamos como fica a importação agora.

inep_esf_docente <- read_xlsx("dados/IED_BRASIL_REGIOES_UFS_2021.xlsx",
                              skip = 10, na = "--")

head(inep_esf_docente)
## # A tibble: 6 × 28
##   NU_ANO_CENSO UNIDGEO NO_CATEGORIA NO_DEPENDENCIA FUN_CAT_1 FUN_CAT_2 FUN_CAT_3 FUN_CAT_4 FUN_CAT_5 FUN_CAT_6 FUN_AI_CAT_1 FUN_AI_CAT_2 FUN_AI_CAT_3
##   <chr>        <chr>   <chr>        <chr>              <dbl>     <dbl>     <dbl>     <dbl>     <dbl>     <dbl>        <dbl>        <dbl>        <dbl>
## 1 2021         Brasil  Total        Total               20.5      17.9      26        27.4       5.4       2.8         32.9         18.3         23.5
## 2 2021         Brasil  Urbana       Total               17.5      17.8      26.9      28.8       5.9       3.1         30.5         19.6         24.1
## 3 2021         Brasil  Rural        Total               31.8      15.7      20.2      24.9       4.7       2.7         44.5          8.9         21.5
## 4 2021         Brasil  Total        Federal             13.9      37.8      30.3      15.5       1.8       0.7         39.4         24.6         25.7
## 5 2021         Brasil  Urbana       Federal             13.6      37.9      30.5      15.6       1.7       0.7         39.2         24.9         25.9
## 6 2021         Brasil  Rural        Federal             33.3      19         4.8      28.6       9.5       4.8         41.8          8.3          8.3
## # … with 15 more variables: FUN_AI_CAT_4 <dbl>, FUN_AI_CAT_5 <dbl>, FUN_AI_CAT_6 <dbl>, FUN_AF_CAT_1 <dbl>, FUN_AF_CAT_2 <dbl>, FUN_AF_CAT_3 <dbl>,
## #   FUN_AF_CAT_4 <dbl>, FUN_AF_CAT_5 <dbl>, FUN_AF_CAT_6 <dbl>, MED_CAT_1 <dbl>, MED_CAT_2 <dbl>, MED_CAT_3 <dbl>, MED_CAT_4 <dbl>, MED_CAT_5 <dbl>,
## #   MED_CAT_6 <dbl>

Ao que parece os dados estão prontos para serem trabalhados!

A função read_xlsx() possui diversos argumentos importantes para trabalharmos a importação de arquivos do MS Excel. Indicamos também o pacote openxlsx (Schauberger e Walker 2021) para manipularmos arquivos desse tipo!

4.1.4 Importando arquivos em JSON

Um formato bastante conhecido para disponibilização de dados quando tratamos de dados abertos é o JSON - JavaScript Object Notation. O JSON é um modelo de transmissão de dados em formato texto, de padrão aberto, e muito usado em web services.

O exemplo que apresentaremos a seguir é da API (Application Programming Interface) disponibilizada pelo Senado Federal para consumo de dados abertos. Alguns dos dados disponíveis estão em JSON e podem ser facilmente obtidos com o pacote jsonlite (Ooms 2014).

Primeiramente vamos entender do que precisamos para fazermos a requisição ao serviço. Os dados estão disponíveis através de uma URL (Uniform Resource Locator), que nada mais é do que um link, um endereço na web. Ao consultar a página da API, constatamos que nossa URL base para os dados de gestão de pessoas é: (“https://adm.senado.gov.br/dadosabertos-gestaopessoas/api/dadosabertos/v1”). A partir dela, podemos adicionar os parâmetros que queremos para fazermos a requisição. Para obter os dados dos servidores comissionados do Senado, basta adicionarmos “/servidores/comissionados” à nossa URL base.

Vamos fazer isso separando a URL base do parâmetro final em duas variáveis texto, após isso vamos usar a função paste0() para unirmos as duas partes. Essa abordagem é importante para irmos visualizando o que é fixo e o que é variável em nossas requisições. Há outros dados que necessitamos passar variáveis dentro da nossa URL de requisição e a função paste0() ajuda bastante nisso.

url_base <- "https://adm.senado.gov.br/dadosabertos-gestaopessoas/api/dadosabertos/v1"
comiss <- "/servidores/comissionados"
url_comiss <- paste0(url_base, comiss) #Usando a função paste0() para unir os dois textos sem espaçamento
url_comiss
## [1] "https://adm.senado.gov.br/dadosabertos-gestaopessoas/api/dadosabertos/v1/servidores/comissionados"

Uma vez que temos nossa URL pronta, vamos utilizar a função fromJSON() do pacote jsonlite. No caso apresentado, vamos usar o argumento flatten == TRUE, para que o data frame retornado não contenha dados aninhados. Feito isso, vamos inspecionar o objeto com_senado, com os dados dos servidores comissionados do Senado Federal, utilizando a função glimpse(), do pacote dplyr. A função é similar à função str().

library(jsonlite)
url_senado <- "https://adm.senado.gov.br/dadosabertos-gestaopessoas/api/dadosabertos/v1/servidores/comissionados"
com_senado <- fromJSON(url_senado, flatten = TRUE)
glimpse(com_senado)
## Rows: 11,106
## Columns: 17
## $ sequencial           <int> 3484998, 3748103, 3749444, 3748987, 3749053, 3749207, 3564622, 3749371, 3749169, 3749355, 3747670, 3444392, 3749118, 3749592, 3…
## $ nome                 <chr> "THALITA MONTEIRO DA BOA MORTE", "ANA PAULA DELMONEGO FLORIANO DE LIMA", "LAURA RIBEIRO MARQUES CAMPOS DE OLIVEIRA", "FRANCISCO…
## $ vinculo              <chr> "COMISSIONADO", "COMISSIONADO", "COMISSIONADO", "COMISSIONADO", "COMISSIONADO", "COMISSIONADO", "COMISSIONADO", "COMISSIONADO",…
## $ situacao             <chr> "ATIVO", "ATIVO", "ATIVO", "ATIVO", "ATIVO", "ATIVO", "ATIVO", "ATIVO", "ATIVO", "ATIVO", "ATIVO", "ATIVO", "ATIVO", "ATIVO", "…
## $ padrao               <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
## $ especialidade        <chr> "AUXILIAR PARLAMENTAR PLENO", "AUXILIAR PARLAMENTAR JÚNIOR", "ASSISTENTE PARLAMENTAR INTERMEDIÁRIO", "AJUDANTE PARLAMENTAR INTE…
## $ ano_admissao         <int> 2022, 2022, 2022, 2022, 2022, 2022, 2022, 2022, 2022, 2022, 2022, 2022, 2022, 2022, 2022, 2022, 2022, 2022, 2022, 2022, 2022, 2…
## $ cargo.nome           <chr> "AUXILIAR PARLAMENTAR PLENO", "AUXILIAR PARLAMENTAR JÚNIOR", "ASSISTENTE PARLAMENTAR INTERMEDIÁRIO", "AJUDANTE PARLAMENTAR INTE…
## $ funcao.codigo        <int> 87, 89, 84, 95, 14, 93, 89, 95, 93, 86, 81, 94, 85, 95, 93, 96, 96, 85, 96, 96, 85, 96, 93, 96, 80, 85, 12, 96, NA, 86, 85, 96,…
## $ funcao.nome          <chr> "AUXILIAR PARLAMENTAR PLENO", "AUXILIAR PARLAMENTAR JÚNIOR", "ASSISTENTE PARLAMENTAR INTERMEDIÁRIO", "AJUDANTE PARLAMENTAR INTE…
## $ lotacao.sigla        <chr> "GLPROS", "E1JMELLO", "ASIMP", "GLPSD", "GLPSD", "QTSECR", "QTSECR", "E1RSANT", "QTSECR", "E1JWAG", "GSASILVE", "GSMVAL", "E1WF…
## $ lotacao.nome         <chr> "Gabinete da Liderança do PROS", "Escritório de Apoio 1 do Senador Jorginho Mello", "Assessoria de Imprensa da Presidência", "G…
## $ categoria.codigo     <chr> "CARGO EM COMISSÃO", "CARGO EM COMISSÃO", "CARGO EM COMISSÃO", "CARGO EM COMISSÃO", "CARGO EM COMISSÃO", "CARGO EM COMISSÃO", "…
## $ categoria.nome       <chr> "CARGO EM COMISSÃO", "CARGO EM COMISSÃO", "CARGO EM COMISSÃO", "CARGO EM COMISSÃO", "CARGO EM COMISSÃO", "CARGO EM COMISSÃO", "…
## $ cedido.tipo_cessao   <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
## $ cedido.orgao_origem  <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
## $ cedido.orgao_destino <lgl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…

Ao que parece a importação ocorreu bem!

O segundo exemplo que iremos apresentar é da API disponibilizada pela Secretaria do Tesouro Nacional em relação aos dados enviados ao Siconfi. Vamos tentar importar os dados dos extratos de entrega dos demonstrativos. Nesse caso específico, precisamos passar dois parâmetros na URL, o identificador do ente e o ano.

O identificador do ente nesse caso nada mais é do que o código IBGE do estado ou município. Iremos exemplificar com o Estado da Paraíba (25) para o ano de 2022.

entrega <- fromJSON("https://apidatalake.tesouro.gov.br/ords/siconfi/tt/extrato_entregas?id_ente=25&an_referencia=2022", flatten = TRUE)

Vamos inspecionar o objeto retornado.

str(entrega)
## List of 6
##  $ items  :'data.frame': 13 obs. of  11 variables:
##   ..$ exercicio       : int [1:13] 2022 2022 2022 2022 2022 2022 2022 2022 2022 2022 ...
##   ..$ cod_ibge        : int [1:13] 25 25 25 25 25 25 25 25 25 25 ...
##   ..$ populacao       : int [1:13] 4059905 4059905 4059905 4059905 4059905 4059905 4059905 4059905 4059905 4059905 ...
##   ..$ instituicao     : chr [1:13] "Assembleia Legislativa do Estado da Paraíba" "Assembleia Legislativa do Estado da Paraíba" "Defensoria Pública do Estado da Paraíba" "Defensoria Pública do Estado da Paraíba" ...
##   ..$ entregavel      : chr [1:13] "MSC Agregada" "MSC Agregada" "MSC Agregada" "MSC Agregada" ...
##   ..$ periodo         : int [1:13] 1 2 1 2 1 2 1 1 2 1 ...
##   ..$ periodicidade   : chr [1:13] "M" "M" "M" "M" ...
##   ..$ status_relatorio: chr [1:13] NA NA NA NA ...
##   ..$ data_status     : chr [1:13] "2022-02-25T18:12:42Z" "2022-03-11T13:24:26Z" "2022-02-25T18:12:42Z" "2022-03-11T13:24:26Z" ...
##   ..$ forma_envio     : chr [1:13] "CSV" "CSV" "CSV" "CSV" ...
##   ..$ tipo_relatorio  : chr [1:13] NA NA NA NA ...
##  $ hasMore: logi FALSE
##  $ limit  : int 5000
##  $ offset : int 0
##  $ count  : int 13
##  $ links  :'data.frame': 3 obs. of  2 variables:
##   ..$ rel : chr [1:3] "self" "describedby" "first"
##   ..$ href: chr [1:3] "http://apidatalake-ords.apps.ocp.tesouro.gov.br/ords/siconfi/tt/extrato_entregas?id_ente=25&an_referencia=2022" "http://apidatalake-ords.apps.ocp.tesouro.gov.br/ords/siconfi/metadata-catalog/tt/item" "http://apidatalake-ords.apps.ocp.tesouro.gov.br/ords/siconfi/tt/extrato_entregas?id_ente=25&an_referencia=2022"

É possível verificar que estamos lidando com uma lista e que há uma série de dados retornados. No entanto, o que interessa para nós é o data.frame contido no primeiro elemento da lista, nomeado como “items”.

entrega[[1]]
##    exercicio cod_ibge populacao                                 instituicao                                  entregavel periodo periodicidade
## 1       2022       25   4059905 Assembleia Legislativa do Estado da Paraíba                                MSC Agregada       1             M
## 2       2022       25   4059905 Assembleia Legislativa do Estado da Paraíba                                MSC Agregada       2             M
## 3       2022       25   4059905     Defensoria Pública do Estado da Paraíba                                MSC Agregada       1             M
## 4       2022       25   4059905     Defensoria Pública do Estado da Paraíba                                MSC Agregada       2             M
## 5       2022       25   4059905                Governo do Estado da Paraíba                                MSC Agregada       1             M
## 6       2022       25   4059905                Governo do Estado da Paraíba                                MSC Agregada       2             M
## 7       2022       25   4059905                Governo do Estado da Paraíba Relatório Resumido de Execução Orçamentária       1             B
## 8       2022       25   4059905     Ministério Público do Estado da Paraíba                                MSC Agregada       1             M
## 9       2022       25   4059905     Ministério Público do Estado da Paraíba                                MSC Agregada       2             M
## 10      2022       25   4059905     Tribunal de Contas do Estado da Paraíba                                MSC Agregada       1             M
## 11      2022       25   4059905     Tribunal de Contas do Estado da Paraíba                                MSC Agregada       2             M
## 12      2022       25   4059905    Tribunal de Justiça do Estado da Paraíba                                MSC Agregada       1             M
## 13      2022       25   4059905    Tribunal de Justiça do Estado da Paraíba                                MSC Agregada       2             M
##    status_relatorio          data_status forma_envio tipo_relatorio
## 1              <NA> 2022-02-25T18:12:42Z         CSV           <NA>
## 2              <NA> 2022-03-11T13:24:26Z         CSV           <NA>
## 3              <NA> 2022-02-25T18:12:42Z         CSV           <NA>
## 4              <NA> 2022-03-11T13:24:26Z         CSV           <NA>
## 5              <NA> 2022-02-25T18:12:41Z         CSV           <NA>
## 6              <NA> 2022-03-11T13:24:25Z         CSV           <NA>
## 7                HO 2022-03-29T13:17:24Z           M              P
## 8              <NA> 2022-02-25T18:12:42Z         CSV           <NA>
## 9              <NA> 2022-03-11T13:24:26Z         CSV           <NA>
## 10             <NA> 2022-02-25T18:12:42Z         CSV           <NA>
## 11             <NA> 2022-03-11T13:24:26Z         CSV           <NA>
## 12             <NA> 2022-02-25T18:12:42Z         CSV           <NA>
## 13             <NA> 2022-03-11T13:24:26Z         CSV           <NA>

4.1.5 Importando grandes quantidades de dados

4.1.5.1 Data.table

Há alguns pacotes que se destacam na leitura de grandes arquivos de dados, iremos destacar dois. O primeiro é o pacote data.table (Dowle e Srinivasan 2021), bastante conhecido não apenas pela sua função de importação, mas pela sua alta performance na manipulação e exportação de arquivos em CSV. O data.tableé um velho conhecido da comunidade R e possui explicações detalhadas em seu site.

No entanto, iremos focar nesse momento na função de leitura de dados fread() para realizarmos a importação de dados, sejam eles em CSV, TXT ou TSV. Vamos instalar nosso pacote (caso ainda não tenha feito), carregá-lo e obter a ajuda da função supramencionada.

library(data.table)
## data.table 1.14.2 using 1 threads (see ?getDTthreads).  Latest news: r-datatable.com
## **********
## This installation of data.table has not detected OpenMP support. It should still work but in single-threaded mode.
## This is a Mac. Please read https://mac.r-project.org/openmp/. Please engage with Apple and ask them for support. Check r-datatable.com for updates, and our Mac instructions here: https://github.com/Rdatatable/data.table/wiki/Installation. After several years of many reports of installation problems on Mac, it's time to gingerly point out that there have been no similar problems on Windows or Linux.
## **********
## 
## Attaching package: 'data.table'
## The following objects are masked from 'package:dplyr':
## 
##     between, first, last
?fread()
fread(input, file, text, cmd, sep="auto", sep2="auto", dec=".", quote="\"",
nrows=Inf, header="auto",
na.strings=getOption("datatable.na.strings","NA"),  # due to change to ""; see NEWS
stringsAsFactors=FALSE, verbose=getOption("datatable.verbose", FALSE),
skip="__auto__", select=NULL, drop=NULL, colClasses=NULL,
integer64=getOption("datatable.integer64", "integer64"),
col.names,
check.names=FALSE, encoding="unknown",
strip.white=TRUE, fill=FALSE, blank.lines.skip=FALSE,
key=NULL, index=NULL,
showProgress=getOption("datatable.showProgress", interactive()),
data.table=getOption("datatable.fread.datatable", TRUE),
nThread=getDTthreads(verbose),
logical01=getOption("datatable.logical01", FALSE),  # due to change to TRUE; see NEWS
keepLeadingZeros = getOption("datatable.keepLeadingZeros", FALSE),
yaml=FALSE, autostart=NA, tmpdir=tempdir(), tz="UTC"
)

Podemos ver que há uma infinidade de argumentos na função fread(). No entanto, iremos destacar alguns dos principais.

Leitura de arquivos compactados: É bastante comum que arquivos com muitos dados seja disponibilizados compactados (normalmente com a extensão *.zip). No Portal dados.gov.br, há mais de 1.000 conjuntos de dados zipados. Porém, para nossa sorte, podemos fazer a importação dos dados sem a necessidade de descompactarmos preliminarmente. A própria função fread() suporta a leitura de arquivos compactados através do argumento cmd=, desde que o unzip esteja instalado em seu computador.

Decimais com vírgula: Assim como outras funções de importação já vistas, podemos alterar o decimal para vírgula através do argumento dec= da função.

Codificação do arquivo: A codificação do arquivo pode ser informada através do argumento encoding=. Normalmente, necessitamos alterá-lo para “Latin-1” ou “UTF8”.

Exclusão de variáveis: Podemos informar uma ou mais variáveis que não desejamos importar, ou seja, excluir desde a importação. Isso é importante para não ocuparmos espaço desnecessariamente.

Leitura de grandes números como texto: Como estamos trabalhando com dados públicos, é comum que grandes números (como CPF, CNPJ ou outro identificador) sejam importados no formato numérico (num). No entanto, por se tratar de um identificador, muitas vezes os mesmos iniciam com um ou mais zeros (Ex.: 00005847870493). Importar tais dados como números faz com que haja perda dessa informação. O mais correto é transformá-los para texto através do argumento integer64=.

Todos os demais argumentos importantes da função fread() trabalham de forma automática, como o separador (sep=). A própria função tenta estabelecer qual o separador utilizado de forma a permitir uma importação menos trabalhosa.

A seguir, apresentamos o exemplo da importação dos dados de empenhos emitidos por municípios paraibanos em 2021. Os dados estão compactados e possuem 1.723.054 observações e 31 variáveis. Uma vez que se trata de arquivo compactado, usaremos o comando unzip -cq antes de apontarmos para o local do arquivo. Iremos excluir da importação o histórico, por economia de espaço em memória, uma vez que se trata de campo com bastante texto; definirmos os “números grandes” como texto e iformarmos a codificação do arquivo como “Latin-1”.

empenhos_2021_mun <- fread(cmd = "unzip -cq  dados/TCE-PB-Empenhos_2021.zip",
                           dec = ",", integer64 = "character", encoding = "Latin-1",
                           drop = "historico")

Inspecionando os dados importados, temos o que segue.

glimpse(empenhos_2021_mun)
## Rows: 1,723,054
## Columns: 31
## $ ano_emissao              <int> 2021, 2021, 2021, 2021, 2021, 2021, 2021, 2021, 2021, 2021, 2021, 2021, 2021, 2021, 2021, 2021, 2021, 2021, 2021, 2021, 202…
## $ data_emissao             <date> 2021-08-12, 2021-08-12, 2021-08-12, 2021-08-13, 2021-08-16, 2021-08-18, 2021-08-20, 2021-08-20, 2021-08-20, 2021-08-20, 20…
## $ numero_empenho           <int> 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145…
## $ cpf_cnpj_credor          <chr> "11459820000162", "11459820000162", "29979036000140", "00005847870493", "09196974000167", "23300440000160", "42598627000136…
## $ tipo_credor              <dbl> 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, …
## $ credor                   <chr> "INSTITUTO DE PREVIDENCIA PROPRIA DE AGUA BRANCA", "INSTITUTO DE PREVIDENCIA PROPRIA DE AGUA BRANCA", "INSS", "JOACIL DE SO…
## $ cod_unidade_gestora      <int> 101001, 101001, 101001, 101001, 101001, 101001, 101001, 101001, 101001, 101001, 101001, 101001, 101001, 101001, 101001, 101…
## $ unidade_gestora          <chr> "Câmara Municipal de Água Branca", "Câmara Municipal de Água Branca", "Câmara Municipal de Água Branca", "Câmara Municipal …
## $ municipio                <chr> "Agua Branca", "Agua Branca", "Agua Branca", "Agua Branca", "Agua Branca", "Agua Branca", "Agua Branca", "Agua Branca", "Ag…
## $ cod_unidade_orcamentaria <int> 10100, 10100, 10100, 10100, 10100, 10100, 10100, 10100, 10100, 10100, 10100, 10100, 10100, 10100, 10100, 10100, 10100, 1010…
## $ unidade_orcamentaria     <chr> "Camara Municipal", "Camara Municipal", "Camara Municipal", "Camara Municipal", "Camara Municipal", "Camara Municipal", "Ca…
## $ numero_licitacao         <chr> "00000/0000", "00000/0000", "00000/0000", "00002/2021", "00000/0000", "00000/0000", "00000/0000", "00001/2021", "00002/2021…
## $ cod_modalidade_licitacao <int> NA, NA, NA, 8, NA, NA, NA, 8, 9, 9, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 8, NA, NA, NA, NA, 8, NA, NA, 9, NA, 9, NA, NA,…
## $ modalidade_licitacao     <chr> "Sem Licitação", "Sem Licitação", "Sem Licitação", "Inexigibilidade", "Sem Licitação", "Sem Licitação", "Sem Licitação", "I…
## $ cod_elemento_despesa     <int> 13, 13, 13, 36, 39, 39, 39, 39, 39, 39, 13, 13, 13, 11, 11, 11, 39, 39, 39, 39, 39, 39, 11, 11, 11, 36, 39, 52, 39, 39, 39,…
## $ elemento_despesa         <chr> "Obrigações Patronais", "Obrigações Patronais", "Obrigações Patronais", "Outros Serviços de Terceiros - Pessoa Física", "Ou…
## $ cod_subelemento_despesa  <int> 99, 99, 99, 38, 42, 42, 61, 61, 61, 61, 99, 99, 99, 97, 96, 97, 50, 49, 49, 57, 61, 61, 97, 96, 97, 38, 42, 73, 61, 61, 61,…
## $ subelemento_despesa      <chr> "SEM SUBELEMENTO", "SEM SUBELEMENTO", "SEM SUBELEMENTO", "OUTROS SERVIÇOS DE PESSOA FÍSICA", "LOCAÇÃO DE SOFTWARES", "LOCAÇ…
## $ cod_fonte_recurso        <int> 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 1001, 100…
## $ fonte_recurso            <chr> "Recursos Ordinários - Recursos do Exercício Corrente", "Recursos Ordinários - Recursos do Exercício Corrente", "Recursos O…
## $ meta                     <chr> "Pessoal", "Pessoal", "Pessoal", "Outras", "Outras", "Outras", "Outras", "Outras", "Outras", "Outras", "Pessoal", "Pessoal"…
## $ cod_categoria_economica  <int> 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, …
## $ categoria_economica      <chr> "Despesa Corrente", "Despesa Corrente", "Despesa Corrente", "Despesa Corrente", "Despesa Corrente", "Despesa Corrente", "De…
## $ cod_modalidade           <int> 91, 91, 90, 90, 90, 90, 90, 90, 90, 90, 91, 91, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90, 90,…
## $ modalidade               <chr> "Aplicação Direta decorrente de Operações entre Órgãos...", "Aplicação Direta decorrente de Operações entre Órgãos...", "Ap…
## $ cod_funcao               <int> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, …
## $ funcao                   <chr> "Legislativa", "Legislativa", "Legislativa", "Legislativa", "Legislativa", "Legislativa", "Legislativa", "Legislativa", "Le…
## $ cod_sub_funcao           <int> 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,…
## $ sub_funcao               <chr> "Ação Legislativa", "Ação Legislativa", "Ação Legislativa", "Ação Legislativa", "Ação Legislativa", "Ação Legislativa", "Aç…
## $ cod_classificacao        <int> 319113, 319113, 319013, 339036, 339039, 339039, 339039, 339039, 339039, 339039, 319113, 319113, 319013, 319011, 319011, 319…
## $ valor_empenho            <dbl> 1812.58, 247.17, 8982.00, 3000.00, 1200.00, 1050.00, 600.00, 3500.00, 1930.00, 1600.00, 1812.58, 247.17, 8982.00, 37000.00,…

Ao que parece a importação ocorreu bem.

4.1.5.2 Vroom

Lançado em 2019, o pacote vroom (Hester, Wickham, e Bryan 2021) é extremamente eficiente na leitura de dados retangulares em CSV, TSV ou arquivos de largura fixa. Tudo isso graças ao seu método de lazy reading, no qual os dados em texto são lidos apenas quando necessário.

Um exemplo muito didático sobre as vantagens do lazy reading é apresentado no blog do Tidyverse. Recentemente o pacote readr incorporou funcionalidades do vroom.

Podemos destacar algumas vantagens da principal função de leitura vroom() do pacote, quais sejam:

  • detecção automática do delimitador do arquivo;
  • leitura e combinação de diversos arquivos;
  • leitura de arquivos compactados (zip, gz, bz2 e xz);
  • leitura de arquivos remotos através da URL do arquivo.

Além das funcionalidades de importação de arquivos, o pacote também possui funções de escrita de arquivos delimitados, algo que veremos mais adiante na parte de exportação de dados.

Assim como os exemplos apresentados até aqui, é recomendável estudarmos um pouco a função e o que ela pode nos oferecer. Para isso, obtenha a ajuda da função (?vroom()).

O arquivo que trabalharemos a seguir traz dados das carreiras, cargos e empregos públicos do Poder Executivo Federal e é disponibilizado no portal de dados abertos do Governo Federal do Brasil. Para fins didáticos, compactamos o arquivo em .zip, uma vez que a nossa função lida com essa extensão.

Vamos tentar ler uma amostra do arquivo passando o argumento n_max = 10. Isso indica que apenas 10 linhas do arquivo serão lidas. Feito isso, vamos inspecionar os dados importados através da função head(). Você também pode usar o visualizador do RStudio!

library(vroom)
carreiras <- vroom("dados/CARREIRA_022022.TXT.zip", n_max = 10)
## Multiple files in zip: reading 'CARREIRA_022022.TXT'
## New names:
## * `` -> ...2
## * `` -> ...3
## * `` -> ...4
## * `` -> ...5
## * `` -> ...6
## * ...
## Warning: One or more parsing issues, see `problems()` for details
## Rows: 10 Columns: 170
## ── Column specification ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
## Delimiter: " "
## chr  (53): CARREIRA.022022, ...2, ...3, ...4, ...5, ...6, ...7, ...8, ...9, ...10, ...11, ...12, ...13, ...14, ...15, ...16, ...17, ...18, ...30, ...31, ....
## lgl (117): ...19, ...20, ...21, ...22, ...23, ...24, ...25, ...26, ...27, ...28, ...29, ...35, ...36, ...48, ...49, ...59, ...60, ...61, ...62, ...63, ......
## 
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
head(carreiras)
## # A tibble: 6 × 170
##   CARREIRA.022022  ...2   ...3   ...4  ...5  ...6  ...7  ...8  ...9  ...10 ...11 ...12 ...13 ...14 ...15 ...16 ...17 ...18 ...19 ...20 ...21 ...22 ...23 ...24
##   <chr>            <chr>  <chr>  <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <chr> <lgl> <lgl> <lgl> <lgl> <lgl> <lgl>
## 1 "Nome;CPF;C\xf3… da     "carr… do    cargo empr… da    UPAG  de    "vin… do    "\xf… de    "atu… de    "ref… da    "rem… NA    NA    NA    NA    NA    NA   
## 2 "THEREZINHA"     NEVES  "MARI… <NA>  <NA>  <NA>  <NA>  <NA>  <NA>   <NA> <NA>   <NA> <NA>   <NA> <NA>   <NA> <NA>   <NA> NA    NA    NA    NA    NA    NA   
## 3 "JACI"           FERNA… "SOBR… <NA>  <NA>  <NA>  <NA>  <NA>  <NA>   <NA> <NA>   <NA> <NA>   <NA> <NA>   <NA> <NA>   <NA> NA    NA    NA    NA    NA    NA   
## 4 "LUIZ"           GONZA… "MEND… CHAG… <NA>  <NA>  <NA>  <NA>  <NA>   <NA> <NA>   <NA> <NA>   <NA> <NA>   <NA> <NA>   <NA> NA    NA    NA    NA    NA    NA   
## 5 "JOAO"           BATIS… "PERE… <NA>  <NA>  <NA>  <NA>  <NA>  <NA>   <NA> <NA>   <NA> <NA>   <NA> <NA>   <NA> <NA>   <NA> NA    NA    NA    NA    NA    NA   
## 6 "ALEXANDRE"      MAGNO  "FELI… GONC… <NA>  <NA>  <NA>  <NA>  <NA>   <NA> <NA>   <NA> <NA>   <NA> <NA>   <NA> <NA>   <NA> NA    NA    NA    NA    NA    NA   
## # … with 146 more variables: ...25 <lgl>, ...26 <lgl>, ...27 <lgl>, ...28 <lgl>, ...29 <lgl>, ...30 <chr>, ...31 <chr>, ...32 <chr>, ...33 <chr>,
## #   ...34 <chr>, ...35 <lgl>, ...36 <lgl>, ...37 <chr>, ...38 <chr>, ...39 <chr>, ...40 <chr>, ...41 <chr>, ...42 <chr>, ...43 <chr>, ...44 <chr>,
## #   ...45 <chr>, ...46 <chr>, ...47 <chr>, ...48 <lgl>, ...49 <lgl>, ...50 <chr>, ...51 <chr>, ...52 <chr>, ...53 <chr>, ...54 <chr>, ...55 <chr>,
## #   ...56 <chr>, ...57 <chr>, ...58 <chr>, ...59 <lgl>, ...60 <lgl>, ...61 <lgl>, ...62 <lgl>, ...63 <lgl>, ...64 <chr>, ...65 <chr>, ...66 <chr>,
## #   ...67 <chr>, ...68 <lgl>, ...69 <chr>, ...70 <chr>, ...71 <lgl>, ...72 <lgl>, ...73 <lgl>, ...74 <chr>, ...75 <lgl>, ...76 <chr>, ...77 <lgl>,
## #   ...78 <chr>, ...79 <chr>, ...80 <lgl>, ...81 <lgl>, ...82 <lgl>, ...83 <lgl>, ...84 <lgl>, ...85 <lgl>, ...86 <lgl>, ...87 <lgl>, ...88 <lgl>,
## #   ...89 <lgl>, ...90 <lgl>, ...91 <lgl>, ...92 <lgl>, ...93 <lgl>, ...94 <lgl>, ...95 <lgl>, ...96 <lgl>, ...97 <lgl>, ...98 <lgl>, ...99 <lgl>, …

Bem, inicialmente vemos que temos alguns problemas a resolver, incluindo o cabeçalho e a codificação.

É sempre bom lembrar que os dados abertos não são perfeitos e tratar esses problemas com o R é um dos objetivos desse curso. Então, vamos lá!

O primeiro argumento que iremos alterar é o skip=, isso porque na primeira linha do arquivo texto não traz as informações do cabeçalho. O segundo argumento que iremos alterar é o locale=. Através dele conseguiremos informar o encoding, que o separador de decimal é a vírgula e o separador de milhar é o ponto. O terceiro argumento a ser modificado é o col_select=, uma vez que identificamos que a nona variável está vazia e sem cabeçalho.

Por fim, uma vez que os nomes das variáveis estão com espaço e alternando maiúsculas e minúsculas, vamos informar um vetor texto com 8 elementos com nomes mais apropriados, algo que pode ser facilmente realizado através do argumento col_names=. Ocorre que passar o nome das colunas no citado argumento fará com que usemos skip=2, sendo a primeira linha ignorada por não se referir a cabeçalho e a segunda devido à exclusão do cabeçalho original.

Vamos ver como fica tudo isso!

nomes_variaveis <- c("nome", "cpf", "cod_carreira", "desc_cargo", "uf_upag_vinc",
                     "orgao", "mes", "valor_rem")
carreiras <- vroom("dados/CARREIRA_022022.TXT.zip", skip = 2, 
                   locale = locale(encoding = "latin1", decimal_mark = ",",
                                   grouping_mark = "."),
                   col_select = c(1:8),
                   col_names = nomes_variaveis)
## Multiple files in zip: reading 'CARREIRA_022022.TXT'
## Rows: 1082844 Columns: 8
## ── Column specification ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
## Delimiter: ";"
## chr (7): nome, cpf, cod_carreira, desc_cargo, uf_upag_vinc, orgao, mes
## 
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
head(carreiras)
## # A tibble: 6 × 8
##   nome                               cpf         cod_carreira desc_cargo                      uf_upag_vinc orgao                        mes   valor_rem
##   <chr>                              <chr>       <chr>        <chr>                           <chr>        <chr>                        <chr>     <dbl>
## 1 THEREZINHA NEVES MARINO            ***010227** 001          ANALISTA DE FINANCAS E CONTROLE DF           CONTROLADORIA-GERAL DA UNIAO 02       27370.
## 2 JACI FERNANDES SOBRINHO            ***225351** 001          ANALISTA DE FINANCAS E CONTROLE DF           CONTROLADORIA-GERAL DA UNIAO 02       15964.
## 3 LUIZ GONZAGA MENDES CHAGAS         ***699967** 001          ANALISTA DE FINANCAS E CONTROLE DF           CONTROLADORIA-GERAL DA UNIAO 02       25033.
## 4 JOAO BATISTA PEREIRA               ***237296** 001          ANALISTA DE FINANCAS E CONTROLE DF           CONTROLADORIA-GERAL DA UNIAO 02       26602.
## 5 ALEXANDRE MAGNO FELIPETO GONCALVES ***651005** 001          ANALISTA DE FINANCAS E CONTROLE DF           CONTROLADORIA-GERAL DA UNIAO 02       12295.
## 6 JORGE MARQUES DA SILVA             ***765307** 001          ANALISTA DE FINANCAS E CONTROLE DF           CONTROLADORIA-GERAL DA UNIAO 02       21012.

Agora sim, tudo importado devidamente!

4.2 Exportando dados no R

Uma vez que tratamos da importação de dados em formatos mais comuns, chegou a hora de utilizarmos alguns pacotes e funções para exportarmos os dados.

4.2.1 Exportando dados em CSV

Assim como existem funções nativas no R para o carregamento de arquivos CSV, há também funções de mesma natureza para realizarmos a exportação. O exemplo que apresentaremos a seguir é o da função write.table(), similar a write.csv().

Iremos utilizar a função write.table() devido a sua flexibilidade. Os dados que iremos exportar são dados contidos no pacote dplyr em um tibble chamado storms. Alteraremos o nosso argumento file= para apontarmos para o local onde desejamos salvar o arquivo bem como o nome do arquivo. Você pode apontar para qualquer local que deseje salvar seus dados em seu computador, mas, uma vez que você esteja trabalhando em um projeto do RStudio o local de salvamento padrão será a pasta do projeto. No nosso caso, iremos salvar o arquivo dentro da pasta exportacoes com o nome de storms.csv.

Além disso, definiremos que o decimal será separado por vírgula, que o separador dos dados será ; e que os valores com NA sejam vazio em nosso arquivo CSV.

write.table(dplyr::storms, file = "exportacoes/storms.csv",
            dec = ",", sep = ";", na = "")

Feito isso, você pode verificar como ficou o arquivo final. Há outros argumentos interessantes na função usada e que podem ser facilmente consultado através da ajuda da função.

4.2.2 Exportando dados em XLSX

Para exportar arquivos em XLSX usaremos o pacote writexl. No nosso exemplo, usaremos a exportação dos dados obtidos do Senado Federal (vide item 4.1.4)). O processo é muito simples, bastando informar o objeto a ser exportado (data frame) e local de salvamento do arquivo XLSX.

library(writexl)
writexl::write_xlsx(com_senado, path = "exportacoes/comissionado_senado.xlsx")

A função writexl() possui uma particularidade interessante. Você pode exportar mais de um data frame em abas diferentes do arquivo XLSX, para isso, basta colocar os objetos em lista. Para esse exemplo, vamos utilizar os dados do Senado Federal utilizados anteriormente e os dados de receitas do item 4.1.1).

Vamos criar uma lista nomeada com os dois data frames e depois passar essa lista como argumento da nossa função de exportação.

exportacao_xlsx <- list(Senado = com_senado, Receitas = receitas)

writexl::write_xlsx(exportacao_xlsx, "exportacoes/com_senado_e_receitas.xlsx")

NOTA: Para exportarmos em XLS podemos utilizar o pacote WriteXLS.

4.2.3 Exportando dados em RDS

O R possui seus próprios formatos de dados, no entanto vamos focar no formato em RDS.

Você pode salvar um objeto R, como um data frame , utilizando um arquivo RData ou um arquivo RDS. Os arquivos RData podem armazenar vários objetos R de uma só vez, mas os arquivos RDS são a melhor escolha porque promovem código reproduzível. (Tradução livre) (Grolemund 2014)

Há algumas vantagens de se utilizar o formato RDS para exportarmos nossos dados, vejamos:

  • O arquivo RDS possui ocupa pouco espaço, uma vez que o mesmo é comprimido;
  • Você salva um objeto por arquivo e isso facilita na hora de escolher o que importar;
  • Você pode carregar o arquivo sem medo de sobrescrever um objeto já existente, uma vez que você vai nomear o objeto que guardará o arquivo carregado.

Para exportarmos em RDS basta utilizarmos a função nativa saveRDS(). Para nosso exemplo, vamos utilizar a lista criada no item anterior.

saveRDS(exportacao_xlsx, file = "exportacoes/dados.RDS")

Referências

Dowle, Matt, e Arun Srinivasan. 2021. data.table: Extension of ‘data.frame‘. https://CRAN.R-project.org/package=data.table.
Grolemund, Garrett. 2014. Hands-on programming with R: Write your own functions and simulations. O’Reilly Media, Inc. https://rstudio-education.github.io/hopr/.
Hester, Jim, Hadley Wickham, e Jennifer Bryan. 2021. vroom: Read and Write Rectangular Text Data Quickly. https://CRAN.R-project.org/package=vroom.
Ooms, Jeroen. 2014. «The jsonlite Package: A Practical and Consistent Mapping Between JSON Data and R Objects». arXiv:1403.2805 [stat.CO]. https://arxiv.org/abs/1403.2805.
Schauberger, Philipp, e Alexander Walker. 2021. openxlsx: Read, Write and Edit xlsx Files. https://CRAN.R-project.org/package=openxlsx.
Wickham, Hadley, e Jennifer Bryan. 2019. readxl: Read Excel Files. https://CRAN.R-project.org/package=readxl.