Como automatizar a leitura de arquivos em diferentes pastas e a criação de colunas em cada base de acordo com o nome do arquivo?

Bom dia,

Preciso ler uma série de arquivos, limpá-los e juntá-los com uma base de municípios do IBGE, um a um, para no final ter uma base com número de anos x 12 x 5570 observações.

Tenho mais de 20 pastas (cada uma referente a um ano) com arquivos em excel dentro delas (cada um referente a um mês/ano), nos quais cada um tem um padrão “nome-mês-ano.xlsx”, sendo o mês em português e apenas com as primeiras três letras (ex: abril se torna abr).

O que preciso fazer, para não copiar o mesmo código mais de 100 vezes, é criar uma função que abra todas as pastas (de ano X a ano Y), leia cada um dos arquivos xlsx e crie duas colunas (mês e ano) a partir das informações no nome do arquivo. Depois, a função deve juntar essa base com a base de municípios, para que finalmente seja jogada em uma base “output” final com as outras bases de 5570 observações para cada mês ano, criando dados em painel para todos os anos e meses.

Consegui limpar uma base como teste e juntar com a base do IBGE, porém sinto que fazer isso para todos os meses/ano seria extremamente ineficiente, por isso a necessidade de automatizar. Não consegui encontrar nenhum exemplo online de função que condicionasse os inputs de colunas ao nome de cada arquivo sendo lido, existe algum pacote ou uma sintaxe que faça isso?

Obrigada desde já!

Olá, Renata.

Nesse caso é necessário criar uma função que faça isso do zero. Eu tentei fazer uma simulação das pastas no meu computador para desenvolver um código que talvez funcione no seu caso, mas pode ser que o código precise ser ajustado. Abaixo eu coloco duas soluções: uma simples e sem usar pacotes do tidyverse e uma mais enxuta que requer alguns conhecimentos mais avançados.

# Solução sem tidyverse
library(lubridate)

# Listar todos os arquivos do diretório "tmp/"
arqs <- list.files("tmp", full.names = TRUE, recursive = TRUE)

# Iterar nos arquivos
output <- data.frame()
for (arq in arqs) {

  # Converter o nome do arquivo em uma data
  mes_ano <- gsub("^.*?-", "", gsub("\\.xlsx", "", basename(arq)))
  data <- dmy(paste0("01-", mes_ano), locale = "pt_BR.UTF-8")

  # Mês e ano
  ano <- year(data)
  mes <- month(data)

  # Ler o arquivo e criar as colunas
  df <- readxl::read_xlsx(arq)
  df[["ano"]] <- ano
  df[["mes"]] <- mes

  # Combinar com o resto das bases
  output <- rbind(output, df)
}

# Ver se o resultado está correto
head(output)
#> # A tibble: 6 × 13
#>     mpg   cyl  disp    hp  drat    wt  qsec    vs    am  gear  carb   ano   mes
#>   <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1  21       6   160   110  3.9   2.62  16.5     0     1     4     4  2018    12
#> 2  21       6   160   110  3.9   2.88  17.0     0     1     4     4  2018    12
#> 3  22.8     4   108    93  3.85  2.32  18.6     1     1     4     1  2018    12
#> 4  21.4     6   258   110  3.08  3.22  19.4     1     0     3     1  2018    12
#> 5  18.7     8   360   175  3.15  3.44  17.0     0     0     3     2  2018    12
#> 6  18.1     6   225   105  2.76  3.46  20.2     1     0     3     1  2018    12

Created on 2021-11-25 by the reprex package (v2.0.1)

# Solução com tidyverse
library(tidyverse)
library(lubridate)
library(fs)

# Realizar todas as operações dentro da tabela
output <- "tmp" %>%
  dir_ls(recurse = TRUE, type = "file") %>%
  map_dfr(readxl::read_xlsx, .id = "arq") %>%
  mutate(
    data = arq %>%
      path_file() %>%
      path_ext_remove() %>%
      str_replace("^.*?-", "01-") %>%
      dmy(locale = "pt_BR.UTF-8"),
    ano = year(data),
    mes = month(data)
  ) %>%
  select(-arq, -data)

# Ver se o resultado está correto
head(output)
#> # A tibble: 6 × 13
#>     mpg   cyl  disp    hp  drat    wt  qsec    vs    am  gear  carb   ano   mes
#>   <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#> 1  21       6   160   110  3.9   2.62  16.5     0     1     4     4  2018    12
#> 2  21       6   160   110  3.9   2.88  17.0     0     1     4     4  2018    12
#> 3  22.8     4   108    93  3.85  2.32  18.6     1     1     4     1  2018    12
#> 4  21.4     6   258   110  3.08  3.22  19.4     1     0     3     1  2018    12
#> 5  18.7     8   360   175  3.15  3.44  17.0     0     0     3     2  2018    12
#> 6  18.1     6   225   105  2.76  3.46  20.2     1     0     3     1  2018    12

Created on 2021-11-25 by the reprex package (v2.0.1)

1 Curtida