Ontem o COPOM decidiu manter a Taxa Selic em 15% por mais um tempo, indicando corte só em março, e hoje me bateu uma curiosidade. Como essa taxa é utilizada para segurar a inflação dentro da sua meta, decidi visualizar como IPCA e Selic se comportaram nos últimos 20 anos.

Para isso, vou usar o pacote ipeadatar para baixar estes dados históricos e o tidyverse para manipulá-los e plotá-los.

library(ipeadatar)
library(tidyverse)
theme_set(theme_minimal())
library(zoo)

Primeiro, preciso descobrir quais são os códigos das séries dentro do banco de dados do IPEA. Para isso, usarei a função available_series e vou filtrar as informações por “nominal” (para encontrar a Selic, taxa nominal de juros) e IPCA.

available_series() |> 
  filter(grepl("nominal", name)) |> 
  print(n = Inf)
## # A tibble: 12 × 7
##    code            name                     theme source freq  lastupdate status
##    <chr>           <chr>                    <fct> <fct>  <fct> <date>     <fct> 
##  1 PAN12_ERV12     Taxa de câmbio nominal   <NA>  Bacen… Mont… 2026-01-05 Active
##  2 PAN4_ERV4       Taxa de câmbio nominal   <NA>  Bacen… Quar… 2026-01-05 Active
##  3 PAN_TJOVER      Taxa de juros nominal -… <NA>  Bacen… Year… 2026-01-01 Active
##  4 PAN12_TJOVER12  Taxa de juros nominal -… <NA>  Bacen… Mont… 2026-01-29 Active
##  5 BM_NFGFNN       NFSP - gov. federal e B… <NA>  Bacen… Year… 2010-03-18 Inact…
##  6 BM12_NFEMNYS12  NFSP - estados e municí… <NA>  Bacen… Mont… 2025-12-30 Inact…
##  7 BM12_NFGFNYS12  NFSP - governo federal … <NA>  Bacen… Mont… 2026-01-12 Inact…
##  8 BM12_NFSPNNAS12 NFSP - setor público - … <NA>  Bacen… Mont… 2025-12-30 Active
##  9 BM12_NFSPNYS12  NFSP - setor público - … <NA>  Bacen… Mont… 2026-01-12 Active
## 10 PAN12_NFSPNYS12 Necessidades de financi… <NA>  Bacen… Mont… 2026-01-12 Active
## 11 PAN4_PIBPMV4    PIB nominal              <NA>  IBGE/… Quar… 2026-01-09 Active
## 12 PAN4_FBKFPIBV4  Taxa de investimento no… <NA>  IPEA   Quar… 2026-01-09 Active
available_series() |> 
  filter(grepl("IPCA", name)) |> 
  print(n = Inf)
## # A tibble: 30 × 7
##    code               name                  theme source freq  lastupdate status
##    <chr>              <chr>                 <fct> <fct>  <fct> <date>     <fct> 
##  1 BM12_IPCA2012      IPCA - núcleo médias… <NA>  Bacen… Mont… 2026-01-12 Active
##  2 BM12_IPCA20N12     IPCA -  núcleo média… <NA>  Bacen… Mont… 2026-01-12 Active
##  3 BM12_IPCACOM12     IPCA - preços livres… <NA>  Bacen… Mont… 2026-01-12 Active
##  4 BM12_IPCAEXC12     IPCA - núcleo por ex… <NA>  Bacen… Mont… 2026-01-12 Active
##  5 BM12_IPCAEXCEX212  IPCA - núcleo por ex… <NA>  Bacen… Mont… 2026-01-12 Active
##  6 BM12_IPCAEXP1212   Expectativa média de… <NA>  Bacen… Mont… 2026-01-06 Active
##  7 BM12_IPCAEXP612    Expectativa média de… <NA>  Bacen… Mont… 2026-01-06 Active
##  8 BM12_IPCANCOM12    IPCA - preços livres… <NA>  Bacen… Mont… 2026-01-12 Active
##  9 BM12_IPCAPL12      IPCA - preços livres… <NA>  Bacen… Mont… 2026-01-12 Active
## 10 BM12_IPCAPLBD12    IPCA - preços livres… <NA>  Bacen… Mont… 2026-01-12 Active
## 11 BM12_IPCAPLBND12   IPCA - preços livres… <NA>  Bacen… Mont… 2026-01-12 Inact…
## 12 BM12_IPCAPLBSD12   IPCA - preços livres… <NA>  Bacen… Mont… 2026-01-12 Inact…
## 13 BM12_IPCAPLSER12   IPCA - preços livres… <NA>  Bacen… Mont… 2026-01-12 Active
## 14 BM12_IPCAPM12      IPCA - preços monito… <NA>  Bacen… Mont… 2026-01-12 Active
## 15 BM12_NUCLEOPIPCA12 Núcleo de dupla pond… <NA>  Bacen… Mont… 2026-01-12 Active
## 16 PRECOS_IPCAG       IPCA - taxa de varia… <NA>  IBGE/… Year… 2026-01-09 Active
## 17 PAN12_IPCAG12      Índice de Preços ao … <NA>  IBGE/… Mont… 2026-01-09 Active
## 18 PRECOS12_IPCA12    IPCA - geral - índic… <NA>  IBGE/… Mont… 2026-01-09 Active
## 19 PRECOS12_IPCA15G12 IPCA - 15 - taxa de … <NA>  IBGE/… Mont… 2026-01-27 Active
## 20 PRECOS12_IPCAAB12  IPCA - alimentos e b… <NA>  IBGE/… Mont… 2026-01-09 Active
## 21 PRECOS12_IPCAAR12  IPCA - artigos de re… <NA>  IBGE/… Mont… 2026-01-09 Active
## 22 PRECOS12_IPCACD12  IPCA - despesas pess… <NA>  IBGE/… Mont… 2026-01-09 Active
## 23 PRECOS12_IPCACO12  IPCA - comunicação -… <NA>  IBGE/… Mont… 2026-01-09 Active
## 24 PRECOS12_IPCAED12  IPCA - educação, lei… <NA>  IBGE/… Mont… 2026-01-09 Active
## 25 PRECOS12_IPCAG12   IPCA - geral - taxa … <NA>  IBGE/… Mont… 2026-01-09 Active
## 26 PRECOS12_IPCAGA12  IPCA - geral - taxa … <NA>  IBGE/… Mont… 2026-01-09 Active
## 27 PRECOS12_IPCAHA12  IPCA - habitação - t… <NA>  IBGE/… Mont… 2026-01-09 Active
## 28 PRECOS12_IPCASC12  IPCA - saúde e cuida… <NA>  IBGE/… Mont… 2026-01-09 Active
## 29 PRECOS12_IPCATC12  IPCA - transportes -… <NA>  IBGE/… Mont… 2026-01-09 Active
## 30 PRECOS12_IPCAVE12  IPCA - vestuário - t… <NA>  IBGE/… Mont… 2026-01-09 Active

Com isso, percebemos que PAN12_TJOVER12 e PRECOS12_IPCAG12 são as séries que queremos para Selic e IPCA, respectivamente.

selic <- ipeadata("PAN12_TJOVER12")
ipca <- ipeadata("PRECOS12_IPCAG12")

Entretanto, temos acesso apenas ao IPCA mensal. Como a Selic é uma taxa anual, criei a função ipca_acumulado para calcular a variação do IPCA para cada período de 12 meses dos dados.

ipca_acumulado <- function(serie){
  (prod(1 + serie/100)-1)*100
}

ipca <- 
  ipca |> 
  mutate(value = rollapply(value, 12, FUN = ipca_acumulado, fill = NA, align = "right"))

Depois, junto os dados de

dados <- 
  ipca |> 
  bind_rows(selic)

dados |> 
  group_by(code) |> 
  summarise(min(date))
## # A tibble: 2 × 2
##   code             `min(date)`
##   <chr>            <date>     
## 1 PAN12_TJOVER12   1974-01-01 
## 2 PRECOS12_IPCAG12 1980-01-01

Como as duas séries iniciam em datas diferentes, resolvi manter os dados apenas a partir de janeiro de 1980. Com isso, o resultado do gráfico comparando ambas as séries é o seguinte:

dados |> 
  filter(date >= ymd("1980-01-01")) |> 
  mutate(code = ifelse(code == "PRECOS12_IPCAG12", "IPCA", "SELIC")) |> 
  ggplot(aes(x = date, y = value, colour = code)) + 
  geom_line() + 
  labs(x = "Data", y = "Valor", colour = "Índice") + 
  scale_y_continuous(labels = scales::comma) + 
  scale_colour_viridis_d()

É incrível ver o nível em que chegavam inflação e taxa básica de juros antes do Plano Real. Para que tenhamos uma visualização mais adequada, vou manter dados apenas a partir de janeiro de 1996:

dados |> 
  filter(date >= ymd("1996-01-01")) |> 
  mutate(code = ifelse(code == "PRECOS12_IPCAG12", "IPCA", "SELIC")) |> 
  ggplot(aes(x = date, y = value, colour = code)) + 
  geom_line() + 
  labs(x = "Data", y = "Valor", colour = "Índice") + 
  scale_y_continuous(labels = scales::comma) + 
  scale_colour_viridis_d()

Como é possível ver, estamos em uma das épocas de maior diferença entre Selic e IPCA. Apenas em meados dos anos 2000 o Brasil passou por uma situação similar. Além disso, o pós-pandemia foi a única época da história do país em que a inflação estava acima da taxa b´åsicade juros.

Particularmente, não sei qual foi a crise que ocorreu no final dos anos 90 (crise da Ásia? crise da Rússia) que fez a Selic disparar tanto, mesmo como a inflação sob controle.