Como tornar um script reproduzível (problemas ao encontrar uma linha específica)?

Prezadxs, olá!

Tenho uma base de arquivos em PDF que possuem cada um uma tabela principal, a qual consegui extrair seguindo os ótimos tutoriais do Julio e do Athos. Contudo, estou tendo dificuldade na parte de “faxina/organização dos dados”.

Essa base traz informações de dois estados separados em duas tabelas, PR e SC, só que essa info não vem em cada tabela , vem no título dela. Uma vez que eu realizo a extração e os ajustes básicos, gero uma única tabela com 2 colunas, uma referente à característica e outra ao preço, onde tenho a info dos dois estados juntas em um dataframe com uma linha específica atuando como “separador”.

Após essa etapa, insiro uma coluna que representa o estado a qual cada linha se refere:

  • dados antes do separador: PR
  • dados após o separador: SC

O problema é que fiz isso de maneira manual, selecionando as linhas com base em dplyr::slice e subset. A base de dados dificilmente vai mudar a ordem porque é bem padronizada, contudo, caso aconteça, o código quebra.

Gostaria de saber como faço para o R identificar onde está o separador e colocar as informações corretas seguindo essa lógica, ao invés de eu definir manualmente o intervalo de linhas.

Dúvida principal:

Como otimizar esse código para ser reproduzível com qualquer quantidade de linhas tanto antes quanto depois do separador? Ou seja, fazer o código identificar o “separador” ao invés da seleção manual das linhas como fiz aqui.

# Exemplo para dúvida sobre linhas e colunas
# 09 fev. 2021
# Maykon G.

# Carregando pacotes
library(tidyverse)

# Cria um dataframe de exemplo
caracteristica <- c("azul", "branco", "amarelo", "separador", "azul", "branco", "vermelho")
reais <- c(15, 20, 25,"",30, 10,80)

database <- data.frame(caracteristica, reais)

# Cria a nova coluna e re-ordena a ordem
database <- database %>% 
  dplyr::mutate(estado = "-") %>% 
  dplyr::select(estado, everything())

database

# Seleciona as linhas ANTES do separador e define um valor para elas
database[1:3, 1] <- database %>% 
  dplyr::select(estado) %>% 

  # quero melhorar isso, porque eventualmente o separador pode estar em outra linha que não a 4
  dplyr::slice(1:3) %>%  
  dplyr::mutate(estado = "PR")

database

# Seleciona as linhas APÓS do separador e define um valor para elas
database[5:7, 1] <- database %>% 
  dplyr::select(estado) %>% 
  dplyr::slice(5:7) %>% 
  dplyr::mutate(estado = "SC")

database

# Deleta a linha de separador
database <- database[-4,]

database


Dúvida extra: reprex()

Tentei rodar reprex::reprex() para trazer o código acima de uma forma mais didática porém obtive o erro abaixo. Alguém tem alguma noção do que pode ser?

# Exemplo para d
---
title: reprex_reprex.R
author: mayko
date: '2021-02-09'

---
#> Error: <text>:10:0: unexpected end of input
#> 8: 
#> 9: ---
#>   ^

Muito obrigado pela atenção e leitura do post!

Abraços.

Oi @maykongpedro!

Usando a base que você criou de exemplo, pensei nessa resolução.

A ideia é numerar as linhas, encontrar com o filtro a linha que faz a separação, e com a função case_when() colocar o nome dos estados…

Faz sentido para você?

# Cria um dataframe de exemplo
caracteristica <- c("azul", "branco", "amarelo", "separador", "azul", "branco", "vermelho")
reais <- c(15, 20, 25,"",30, 10,80)

database <- tibble::tibble(caracteristica, reais)

# numera as linhas!
base_numerada <- database %>% 
  dplyr::mutate(id = dplyr::row_number())

# encontrar o numero da linha que separa
linha_separacao <- base_numerada %>% 
  dplyr::filter(caracteristica == "separador") %>% 
  dplyr::select(id) %>% 
  dplyr::pull()

# Adicionar a coluba de estados, e remover a linha de separação
base_final <- base_numerada %>%
  # colocar os estados
  dplyr::mutate(estado = dplyr::case_when(id < linha_separacao ~ "PR",
                                          id > linha_separacao ~ "SC")) %>%
  # remover linha separadora
  dplyr::filter(!caracteristica == "separador") %>% 
  # remover linha do id
  dplyr::select(-id)

base_final 

# > base_final 
# # A tibble: 7 x 3
# caracteristica reais estado
# <chr>          <chr> <chr> 
#   1 azul           15    PR    
# 2 laranja        10    PR    
# 3 branco         20    PR    
# 4 amarelo        25    PR    
# 5 azul           30    SC    
# 6 branco         10    SC    
# 7 vermelho       80    SC
1 Curtida

Faz muito sentido sim!
É exatamente o que eu precisava, muito obrigado!
Não tinha conhecimento da função dplyr::pull, achei mais prático que o uso do $. E também não tinha experiência com case_when, muito mais versátil que a seleção manual.
E no fim dava pra resolver tudo com funções básicas do tidyverse, show de bola.
Obrigado pela ajuda.

1 Curtida

Que bom que ajudou!

A função dplyr::case_when() merece muito um post para o blog hahah essa função é muito útil mesmo!

1 Curtida