Dados Corporativos no R

Workshop UFSM

Marcelo S. Perlin

EA-UFRGS

27/08/2026

classtools::setup_quarto_slides("templates")

Motivação

Documentos financeiros e pesquisa

Demonstrações financeiras são o cerne dos estudos de finanças corporativas (Perlin et al. 2019).

  • “Accessing financial reports and corporate events with GetDFPData”, RBFIN 2019
    • em selecionadas revistas Qualis A2/B1, em torno de 70% dos estudos de finanças entre 2013-2017 se utilizaram do economática
    • O economática, na época, só permitia operações do tipo copia e cola
    • A B3 oferece acesso público aos seus conjuntos de dados em quatro sistemas diferentes: DFP, ITR, FRE e FCA, mas com várias limitações para o acesso em larga escala.

Os sistemas da B3 e da CVM

DFP e FRE (Exemplo para Petrobrás )

Sistema DFP

Sistema FRE

Dados da CVM

Portal de Dados CVM

Pacotes GetDFPData2 e GetFREData

Sobre o R

O R é uma linguagem de programação voltada para a resolução de problemas estatísticos e para a visualização gráfica de dados.

Autores
Ross Ihaka e Robert Gentleman (The University of Auckland)
Funcionalidade
R é sinônimo de programação voltada à análise de dados
Custo
O R é totalmente livre e disponível em vários sistemas operacionais.

Curiosidades e funcionalidades

  • A primeira versão do pacote foi uma tentativa de atualizar slides e exercícios da graduação automaticamente (Rmarkdown/quarto)

  • Inicialmente, pacote GetDFPdata agregava dados do DFP e FRE juntamente. Posteriormente, separei os pacotes entre GetDFPData2 e GetFREData

GetDFPData2 fornece uma interface R aberta para todas as demonstrações financeiras anuais distribuídas pela B3 e CVM: DRE, BP, DFC, DMPL, DVA

GetFREData permite download de tabelas do sistema FRE (Formulário de Referencia): controle acionário, membros do conselho de administração, remuneração dos conselheiros, relações familiares, entre váriso outros

Workshop

Pacote GetDFPData2 – Exemplo 01 (Grendene)

Passo 01: instalar pacote

install.packages("GetDFPData2")

Passo 02: baixar dados das empresas disponíveis

cache_folder <- "~/.cache/gdfpd2_cache"

df_info <- GetDFPData2::get_info_companies(
  cache_folder
)

df_info |>
  dplyr::glimpse()
Rows: 2,677
Columns: 47
$ CNPJ               <chr> "08.773.135/0001-00", "11.396.633/0001-87", "01.547…
$ DENOM_SOCIAL       <chr> "2W ECOBANK S.A. - EM RECUPERAÇÃO JUDICIAL", "3A CO…
$ DENOM_COMERC       <chr> "2W ECOBANK S.A.", "TRIPLO A  COMPANHIA SECURITIZAD…
$ DT_REG             <date> 2020-10-29, 2010-03-08, 1997-07-11, 1997-05-30, 19…
$ DT_CONST           <date> 2007-03-23, 2009-11-03, 1996-07-30, 1997-04-02, 19…
$ DT_CANCEL          <date> NA, 2015-12-18, NA, NA, 2006-05-30, 1998-06-17, 20…
$ MOTIVO_CANCEL      <chr> NA, "CANCELAMENTO VOLUNTÁRIO", NA, NA, "ELISÃO POR …
$ SIT_REG            <chr> "SUSPENSO(A) - DECISÃO ADM", "CANCELADA", "ATIVO", …
$ DT_INI_SIT         <date> 2026-05-19, 2015-12-18, 1997-07-11, 1997-05-30, 20…
$ CD_CVM             <dbl> 25224, 21954, 16330, 16284, 16349, 35, 16802, 13307…
$ SETOR_ATIV         <chr> "Energia Elétrica", "Securitização de Recebíveis", …
$ TP_MERC            <chr> NA, NA, NA, "BOLSA", NA, NA, NA, NA, NA, NA, NA, NA…
$ CATEG_REG          <chr> "Categoria A", "Categoria B", "Categoria B", "Categ…
$ DT_INI_CATEG       <date> 2020-10-29, 2010-03-08, 2011-04-28, 2010-01-01, NA…
$ SIT_EMISSOR        <chr> "EM RECUPERAÇÃO JUDICIAL OU EQUIVALENTE", "FASE PRÉ…
$ DT_INI_SIT_EMISSOR <date> 2025-04-23, 2010-03-08, 2015-04-30, 1997-05-30, NA…
$ CONTROLE_ACIONARIO <chr> "PRIVADO", "PRIVADO", "PRIVADO", "PRIVADO", "PRIVAD…
$ TP_ENDER           <chr> "SEDE", "SEDE", "SEDE", "SEDE", "SEDE", "SEDE", "SE…
$ LOGRADOURO         <chr> "Avenida Dr. Chucri Zaidan, 1550", "Avenida Erasmo …
$ COMPL              <chr> "8 and-conj 815-sl 1", "sala 703", "3000 - sala 409…
$ BAIRRO             <chr> "Chacara Santo Antoni", "Centro", "Barra da Tijuca"…
$ MUN                <chr> "SÃO PAULO", "RIO DE JANEIRO", "RIO DE JANEIRO", "R…
$ UF                 <chr> "SP", "RJ", "RJ", "RJ", "RJ", "RS", "RJ", "SP", "RJ…
$ PAIS               <chr> "BRASIL", "BRASIL", "BRASIL", "BRASIL", "BRASIL", "…
$ CEP                <dbl> 4711130, 20020000, 22775003, 20020010, 22290160, 90…
$ DDD_TEL            <chr> "11", "21", "21", "21", "21", "51", "21", "11", "24…
$ TEL                <dbl> 39579400, 22338867, 25560809, 38043700, 21967200, 3…
$ DDD_FAX            <chr> "11", "21", "21", "21", "21", "51", "21", NA, "24",…
$ FAX                <dbl> 39579499, 22338867, 25560809, 38043480, 21967201, 3…
$ EMAIL              <chr> "ri@2wecobank.com.br", "dri@3asec.com.br", "eximia@…
$ TP_RESP            <chr> "DIRETOR DE RELAÇÕES COM INVESTIDORES", "DIRETOR DE…
$ RESP               <chr> "FERNANDO GUEDES VIEIRA", "FELIPE MARQUES DA FONSEC…
$ DT_INI_RESP        <date> 2026-04-22, 2011-06-16, NA, 2026-05-06, 2005-06-14…
$ LOGRADOURO_RESP    <chr> "AV DR. CHUCRI ZAIDAN, 1550", "AVENIDA ERASMO BRAGA…
$ COMPL_RESP         <chr> "8 AND-CONJ815-SL1", "SALA 703", NA, "51", "2201 (P…
$ BAIRRO_RESP        <chr> "CHÁCARA STO. ANTÔNIO", "CENTRO", NA, "Centro", "BO…
$ MUN_RESP           <chr> "SÃO PAULO", "RIO DE JANEIRO", NA, "RIO DE JANEIRO"…
$ UF_RESP            <chr> "SP", "RJ", NA, "RJ", "RJ", "RS", "MG", "SP", "RJ",…
$ PAIS_RESP          <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
$ CEP_RESP           <dbl> 4711130, 20020000, NA, 20020010, 22290160, 90000000…
$ DDD_TEL_RESP       <chr> "11", "21", NA, "21", "21", "51", "31", "21", "24",…
$ TEL_RESP           <dbl> 39579400, 22338867, NA, 38043700, 21967200, 3142033…
$ DDD_FAX_RESP       <chr> NA, "21", NA, NA, "21", "0051", "31", "0021", "24",…
$ FAX_RESP           <dbl> NA, 22338867, NA, NA, 21967201, 3743595, 32737218, …
$ EMAIL_RESP         <chr> "juridico@2wecobank.com.br", "juridico@triploasec.c…
$ CNPJ_AUDITOR       <chr> "10.830.108/0001-65", "60.525.706/0001-07", "02.878…
$ AUDITOR            <chr> "GRANT THORNTON AUDITORES INDEPENDENTES LTDA.", "MO…



Passo 03: identificar empresas

df_search <- GetDFPData2::search_company("grendene")
df_search
# A tibble: 1 × 3
  CD_CVM DENOM_SOCIAL SIT_REG
   <dbl> <chr>        <chr>  
1  19615 GRENDENE SA  ATIVO  



Passo 04: baixar os dados

id_company <- 19615 # Grendene
first_year <- 2015
last_year <- 2023

# download data
l_dfp <- GetDFPData2::get_dfp_data(
  companies_cvm_codes = id_company,
  first_year = first_year,
  last_year = last_year,
  cache_folder = cache_folder
)

names(l_dfp)
[1] "DF Consolidado - Balanço Patrimonial Ativo"  
[2] "DF Consolidado - Balanço Patrimonial Passivo"
[3] "DF Consolidado - Demonstração do Resultado"  
[4] "DF Individual - Balanço Patrimonial Ativo"   
[5] "DF Individual - Balanço Patrimonial Passivo" 
[6] "DF Individual - Demonstração do Resultado"   



Passo 05: checar os dados

bp_con <- l_dfp$`DF Consolidado - Demonstração do Resultado`  

dplyr::glimpse(bp_con)
Rows: 284
Columns: 16
$ CNPJ_CIA     <chr> "89.850.341/0001-60", "89.850.341/0001-60", "89.850.341/0…
$ CD_CVM       <dbl> 19615, 19615, 19615, 19615, 19615, 19615, 19615, 19615, 1…
$ DT_REFER     <date> 2015-12-31, 2015-12-31, 2015-12-31, 2015-12-31, 2015-12-…
$ DT_INI_EXERC <date> 2015-01-01, 2015-01-01, 2015-01-01, 2015-01-01, 2015-01-…
$ DT_FIM_EXERC <date> 2015-12-31, 2015-12-31, 2015-12-31, 2015-12-31, 2015-12-…
$ DENOM_CIA    <chr> "GRENDENE S.A.", "GRENDENE S.A.", "GRENDENE S.A.", "GREND…
$ VERSAO       <dbl> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, …
$ GRUPO_DFP    <chr> "DF Consolidado - Demonstração do Resultado", "DF Consoli…
$ MOEDA        <chr> "REAL", "REAL", "REAL", "REAL", "REAL", "REAL", "REAL", "…
$ ESCALA_MOEDA <chr> "MIL", "MIL", "MIL", "MIL", "MIL", "MIL", "MIL", "MIL", "…
$ ORDEM_EXERC  <chr> "ÚLTIMO", "ÚLTIMO", "ÚLTIMO", "ÚLTIMO", "ÚLTIMO", "ÚLTIMO…
$ CD_CONTA     <chr> "3.01", "3.02", "3.03", "3.04", "3.04.01", "3.04.02", "3.…
$ DS_CONTA     <chr> "Receita de Venda de Bens e/ou Serviços", "Custo dos Bens…
$ VL_CONTA     <dbl> 2202796, -1134913, 1067883, -667151, -523709, -102570, 0,…
$ COLUNA_DF    <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
$ source_file  <chr> "dfp_cia_aberta_DRE_con_2015.csv", "dfp_cia_aberta_DRE_co…



Passo 06: analisar margem de lucro

tbl_ind <- bp_con |>
  dplyr::group_by(CD_CVM, DENOM_CIA, DT_REFER) |>
  dplyr::summarise(
    margem_liq =  VL_CONTA[CD_CONTA == "3.11"]/VL_CONTA[CD_CONTA == "3.01"] # LL/Vendas
  ) |>
  dplyr::ungroup()

tbl_ind |>
  gt::gt() |>
  gt::tab_header("Margem de Lucro da Grendene") |>
  gt::fmt_percent(margem_liq)
Margem de Lucro da Grendene
CD_CVM DENOM_CIA DT_REFER margem_liq
19615 GRENDENE S.A. 2015-12-31 24.48%
19615 GRENDENE S.A. 2016-12-31 31.00%
19615 GRENDENE S.A. 2017-12-31 29.35%
19615 GRENDENE S.A. 2018-12-31 25.09%
19615 GRENDENE S.A. 2019-12-31 23.90%
19615 GRENDENE S.A. 2020-12-31 21.36%
19615 GRENDENE S.A. 2021-12-31 25.66%
19615 GRENDENE S.A. 2022-12-31 22.61%
19615 GRENDENE S.A. 2023-12-31 22.92%



Passo 04 - analisar a Grendene

tbl_ind_company <- tbl_ind |>
  dplyr::filter(CD_CVM == 1023)

Pacote GetDFPData2 – Exemplo 02 (todas empresas)

Passo 01 - baixar dados de todas empresas

df_info <- GetDFPData2::get_info_companies(
  cache_folder
)

ids <- df_info$CD_CVM |> 
  unique()

l_dfp <- GetDFPData2::get_dfp_data(
    companies_cvm_codes = ids,
    first_year = 2010, 
    type_docs = "DRE",
    cache_folder = cache_folder
)



Passo 02 - checar os dados

bp_con <- l_dfp$`DF Consolidado - Demonstração do Resultado`  
dplyr::glimpse(bp_con)
Rows: 221,705
Columns: 16
$ CNPJ_CIA     <chr> "00.000.000/0001-91", "00.000.000/0001-91", "00.000.000/0…
$ CD_CVM       <dbl> 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 1023, 102…
$ DT_REFER     <date> 2010-12-31, 2010-12-31, 2010-12-31, 2010-12-31, 2010-12-…
$ DT_INI_EXERC <date> 2010-01-01, 2010-01-01, 2010-01-01, 2010-01-01, 2010-01-…
$ DT_FIM_EXERC <date> 2010-12-31, 2010-12-31, 2010-12-31, 2010-12-31, 2010-12-…
$ DENOM_CIA    <chr> "BCO BRASIL S.A.", "BCO BRASIL S.A.", "BCO BRASIL S.A.", …
$ VERSAO       <dbl> 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, …
$ GRUPO_DFP    <chr> "DF Consolidado - Demonstração do Resultado", "DF Consoli…
$ MOEDA        <chr> "REAL", "REAL", "REAL", "REAL", "REAL", "REAL", "REAL", "…
$ ESCALA_MOEDA <chr> "MIL", "MIL", "MIL", "MIL", "MIL", "MIL", "MIL", "MIL", "…
$ ORDEM_EXERC  <chr> "ÚLTIMO", "ÚLTIMO", "ÚLTIMO", "ÚLTIMO", "ÚLTIMO", "ÚLTIMO…
$ CD_CONTA     <chr> "3.01", "3.01.01", "3.02", "3.02.01", "3.02.02", "3.03", …
$ DS_CONTA     <chr> "Receitas da Intermediação Financeira", "Receita de Juros…
$ VL_CONTA     <dbl> 85143206, 85143206, -50775741, -43061187, -7714554, 34367…
$ COLUNA_DF    <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
$ source_file  <chr> "dfp_cia_aberta_DRE_con_2010.csv", "dfp_cia_aberta_DRE_co…



Passo 03 - calcular margens de lucro

tbl_ind <- bp_con |>
  dplyr::group_by(CD_CVM, DENOM_CIA, DT_REFER) |>
  dplyr::reframe(
    margem_liq =  VL_CONTA[CD_CONTA == "3.11"]/VL_CONTA[CD_CONTA == "3.01"] # LL/Vendas
  ) |>
  dplyr::ungroup()

dplyr::glimpse(tbl_ind)
Rows: 6,015
Columns: 4
$ CD_CVM     <dbl> 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,…
$ DENOM_CIA  <chr> "PANATLANTICA S.A.", "PANATLANTICA S.A.", "PANATLANTICA S.A…
$ DT_REFER   <date> 2010-12-31, 2011-12-31, 2012-12-31, 2013-12-31, 2014-12-31…
$ margem_liq <dbl> 0.052869467, 0.036396859, 0.041271273, 0.086840074, 0.02109…

Pacote GetFREData - exemplo 01 (grendene)

Passo 01 - baixar dados da Grendene

id_company <- 19615 # Grendene
first_year <- 2015
last_year <- 2022

# download data
l_fre <- GetFREData::get_fre_data2(
  first_year = first_year,
  last_year = last_year,
  cache_folder = cache_folder
)



Passo 02 - checar os dados

names(l_fre)
 [1] "fre_cia_aberta"                                             
 [2] "fre_cia_aberta_administrador_membro_conselho_fiscal"        
 [3] "fre_cia_aberta_ativo_imobilizado"                           
 [4] "fre_cia_aberta_ativo_intangivel"                            
 [5] "fre_cia_aberta_auditor"                                     
 [6] "fre_cia_aberta_auditor_responsavel"                         
 [7] "fre_cia_aberta_capital_social"                              
 [8] "fre_cia_aberta_capital_social_aumento"                      
 [9] "fre_cia_aberta_capital_social_aumento_classe_acao"          
[10] "fre_cia_aberta_capital_social_classe_acao"                  
[11] "fre_cia_aberta_capital_social_desdobramento"                
[12] "fre_cia_aberta_capital_social_desdobramento_classe_acao"    
[13] "fre_cia_aberta_capital_social_reducao"                      
[14] "fre_cia_aberta_capital_social_reducao_classe_acao"          
[15] "fre_cia_aberta_capital_social_titulo_conversivel"           
[16] "fre_cia_aberta_direito_acao"                                
[17] "fre_cia_aberta_distribuicao_capital"                        
[18] "fre_cia_aberta_distribuicao_capital_classe_acao"            
[19] "fre_cia_aberta_distribuicao_dividendos"                     
[20] "fre_cia_aberta_distribuicao_dividendos_classe_acao"         
[21] "fre_cia_aberta_endividamento"                               
[22] "fre_cia_aberta_grupo_economico_reestruturacao"              
[23] "fre_cia_aberta_historico_emissor"                           
[24] "fre_cia_aberta_informacao_financeira"                       
[25] "fre_cia_aberta_membro_comite"                               
[26] "fre_cia_aberta_obrigacao"                                   
[27] "fre_cia_aberta_outro_valor_mobiliario"                      
[28] "fre_cia_aberta_participacao_sociedade"                      
[29] "fre_cia_aberta_participacao_sociedade_valorizacao_acao"     
[30] "fre_cia_aberta_plano_recompra"                              
[31] "fre_cia_aberta_plano_recompra_classe_acao"                  
[32] "fre_cia_aberta_politica_negociacao"                         
[33] "fre_cia_aberta_politica_negociacao_cargo"                   
[34] "fre_cia_aberta_posicao_acionaria"                           
[35] "fre_cia_aberta_posicao_acionaria_classe_acao"               
[36] "fre_cia_aberta_relacao_familiar"                            
[37] "fre_cia_aberta_relacao_subordinacao"                        
[38] "fre_cia_aberta_remuneracao_maxima_minima_media"             
[39] "fre_cia_aberta_remuneracao_total_orgao"                     
[40] "fre_cia_aberta_responsavel"                                 
[41] "fre_cia_aberta_transacao_parte_relacionada"                 
[42] "fre_cia_aberta_valor_mobiliario_tesouraria_movimentacao"    
[43] "fre_cia_aberta_valor_mobiliario_tesouraria_ultimo_exercicio"
[44] "fre_cia_aberta_volume_valor_mobiliario"                     
[45] "fre_cia_aberta_titulo_exterior"                             
[46] "fre_cia_aberta_titular_valor_mobiliario"                    
[47] "fre_cia_aberta_mercado_estrangeiro"                         



Passo 03- analisar composição atual do conselho

df_boards <- l_fre$fre_cia_aberta_membro_comite
last_year <- max(df_boards$data_referencia)

df_board_current <- df_boards |>
  dplyr::filter(data_referencia == last_year)

df_board_current |>
  dplyr::select(nome,
                cpf, profissao,data_nascimento,
                data_eleicao) |>
  gt::gt() |>
  gt::tab_header(
    title = "Composição do Conselho -- GRENDENE", 
    subtitle = glue::glue("Dados para {last_year}"))
Composição do Conselho -- GRENDENE
Dados para 2022-06-30
nome cpf profissao data_nascimento data_eleicao
Alejandro G. Elsztain 232.445.688-58 Engenheiro Agropecuário 1966-03-31 2021-11-03
Isaac Selim Sutton 047.010.738-30 Economista 1960-10-25 2021-11-03
Eliane Aleixo 783.519.367-15 Economista 1963-02-05 2021-11-03
Rafael Espinola de Vasconcelos 023.957.687-07 Engenheiro NA 2021-11-03
Isabella Saboya 017.919.007-55 Empresária 1970-08-25 2021-11-03
Alejandro Gustavo Casaretto NA Engenheiro Agrônomo 1952-10-15 2021-10-27
Alejandro Gustavo Casaretto NA Engenheiro Agrônomo 1952-10-15 2021-10-27
Maria Fernanda dos Santos Teixeira 765.087.908-97 Administradora 1952-08-10 2022-02-14
André José Valério 300.848.918-40 Contador 1982-10-20 2021-08-17
Silvio José Genesini Júnior 607.689.408-34 Engenheiro 1952-10-27 2021-10-19

Aprendizado

  • Existe uma variedade imensa de dados públicos que podem ser usados em pesquisa
  • Raspagem de dados de sites é momentânea e não-sustentável!
    • procura uma maneira oficial de coletar dados
    • evite raspar dados da B3!
  • Cuidado com os dados que são raspados sem consentimento!
  • O código vai evoluir, quanto mais simples, melhor..

Próximos passos e dicas pacotes

Próximos passos

  1. Nova versão atualizada
    • revisar código
    • novo sistema de cacheamento
    • arrumar nomes das colunas
    • gestão de erros em download
    • usar dados da CVM (e não B3)
  2. Olhar outros dados da CVM
  3. Desenvolver pacote equivalente para dados do Edgar/SEC/USA

Um acesso mais direto aos dados

Anualmente, um script importa todos os dados disponíveis na B3, organiza os dados e disponibiliza no site https://msperlin.com/data/

Dataverse

Produções resultantes

REICHERT, M. ; PERLIN, M. S. . What Drives the Release of Material Facts for Brazilian Stocks?. REVISTA BRASILEIRA DE FINANÇAS (IMPRESSO), v. 20, p. 01-15, 2022.

MASTELLA, M. ; PERLIN, MARCELO S. ; KIRCH, G. ; VANCIN, D. . Board gender diversity: performance and risk of Brazilian firms. GENDER IN MANAGEMENT (PRINT), v. ahead-of-print, p. 1-30, 2021. Citações:16|19

PERLIN, M. S.; KIRCH, G. ; MASTELLA, M. ; VANCIN, D. . O Impacto Da Titulação Acadêmica De Conselheiros E Diretores Sobre A Performance De Empresas Negociadas Na B3. BBR. BRAZILIAN BUSINESS REVIEW (EDIÇÃO EM PORTUGUÊS. ONLINE), v. 18, p. 561-584, 2021.

PERLIN, M. S.; KIRCH, G. ; VANCIN, D. . Accessing financial reports and corporate events with GetDFPData. REVISTA BRASILEIRA DE FINANÇAS: RBFIN = RBFIN: BRAZILIAN FINANCE REVIEW, v. 17, p. 85, 2019.

+38 citações do pacote em artigo publicado

Curiosidades

Livros do R

Introdução ao R – Um guia prático para iniciantes

Programação e Análise de Dados com o R

  • Em desenvolvimento!
  • Provável publicação em 2025

Visualização de Dados com o R

Questões de R em Concursos Públicos

Referências

Perlin, Marcelo S, Guilherme Kirch, and Daniel Vancin. 2019. “Accessing Financial Reports and Corporate Events with GetDFPData.” Brazilian Review of Finance 17 (3): 85–108.