Automatizar seleção de arquivos pelo nome

Oi pessoal, tudo bem? Estou com dificuldade e pouca criativa para solucionar a seguinte situação:

Tenho uma pasta com vários metadados (são arquivos em Extensible Markup Language -XML). Cada arquivo tem um nome que representa na sequência 1- o nome do autor, 2- numeração do dataset e 3- versão do dataset (ex.: souza_1_1).

O que eu preciso é de um dataframe final como este do exemplo que vou criar aqui (Bind_all), com metadados mais atuais por autores e dataset.

library(dplyr)
#> 
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#> 
#>     filter, lag
#> The following objects are masked from 'package:base':
#> 
#>     intersect, setdiff, setequal, union
library(stringr)

metadata_all = c("costa_1_1", "costa_1_2", "costa_1_3", "costa_13_12", "costa_13_13", "silva_2_11", "silva_2_12", "silva_2_13", "silva_13_10", "silva_13_13", "souza_190_10", "souza_190_11", "souza_190_13", "souza_191_1", "souza_191_13")

metadata_all= as.data.frame(metadata_all)

metadata_all
#>    metadata_all
#> 1     costa_1_1
#> 2     costa_1_2
#> 3     costa_1_3
#> 4   costa_13_12
#> 5   costa_13_13
#> 6    silva_2_11
#> 7    silva_2_12
#> 8    silva_2_13
#> 9   silva_13_10
#> 10  silva_13_13
#> 11 souza_190_10
#> 12 souza_190_11
#> 13 souza_190_13
#> 14  souza_191_1
#> 15 souza_191_13

costa = metadata_all |> 
  filter(str_detect(metadata_all,"^costa")) |>  
  arrange(desc(metadata_all)) |> 
  filter((metadata_all %in% c("costa_1_3", "costa_13_13"))) # Selecionando os datasets mais atuais de Costa. 

silva = metadata_all |> 
  filter(str_detect(metadata_all,"^silva")) |>  
  arrange(desc(metadata_all)) |> 
  filter((metadata_all %in% c("silva_2_13", "silva_13_13"))) # Selecionando os datasets mais atuais de Silva 

souza = metadata_all |> 
  filter(str_detect(metadata_all,"^souza")) |>  
  arrange(desc(metadata_all)) |> 
  filter((metadata_all %in% c("souza_190_13", "souza_191_13"))) # Selecionando os datasets mais atuais de Souza 


Bind_all = bind_rows(costa, silva, souza) 
Bind_all
#>   metadata_all
#> 1  costa_13_13
#> 2    costa_1_3
#> 3   silva_2_13
#> 4  silva_13_13
#> 5 souza_191_13
#> 6 souza_190_13

Created on 2022-09-21 by the reprex package (v2.0.1)

O questão é que tenho muitos autores e cada autor com muitos datasets. Está me custando muito tempo pra fazer desse jeito, mas foi a única maneira que consegui até agora. Fico muito grata se alguém me ajudar a pensar em algo mais eficiente.

Tai, minha sugestão é usar a função separate() do tidyr, agrupar por nome e numeração, e depois fazer um slice_max(). A separate() vai quebrar o metadado nos underlines e criar novas colunas, então você pode agrupar só pelo nome e numeração; aí você pode usar a slice_max() para pegar a linha com a maior versão de cada grupo. Veja se o código abaixo está claro:

# Dados
dados <- c(
  "costa_1_1", "costa_1_2", "costa_1_3", "costa_13_12", "costa_13_13",
  "silva_2_11", "silva_2_12", "silva_2_13", "silva_13_10", "silva_13_13",
  "souza_190_10", "souza_190_11", "souza_190_13", "souza_191_1", "souza_191_13"
)

# Tabela exemplo
metadata_all <- tibble::tibble(metadata = dados)

metadata_all |>
  tidyr::separate(metadata, c("name", "id", "version"), remove = FALSE) |>
  dplyr::mutate(id = as.numeric(id), version = as.numeric(version)) |>
  dplyr::group_by(name, id) |>
  dplyr::slice_max(version, n = 1) |>
  dplyr::ungroup()
#> # A tibble: 6 × 4
#>   metadata     name     id version
#>   <chr>        <chr> <dbl>   <dbl>
#> 1 costa_1_3    costa     1       3
#> 2 costa_13_13  costa    13      13
#> 3 silva_2_13   silva     2      13
#> 4 silva_13_13  silva    13      13
#> 5 souza_190_13 souza   190      13
#> 6 souza_191_13 souza   191      13

Created on 2022-09-21 with reprex v2.0.2
P.S.: Eu troquei o nome da coluna metadata_all para metadata porque eu estava confundindo a coluna com a tabela. Mas pode fazer do jeito que você achar melhor.

1 curtida

Sua solução vai otimizar quase um mês de trabalho por aqui! Muito obrigada @clente !!

1 curtida