Autor

Bruno Henrique e Lucas Felipe

Data de Publicação

17/09/2026, 21:39

1 📌 Introdução

No contexto da Engenharia Civil, o controle tecnológico do concreto desempenha um papel fundamental na verificação da qualidade e do desempenho dos materiais empregados nas obras. Durante a execução de um empreendimento, são produzidos diversos dados provenientes de ensaios laboratoriais, registros de campo e informações relacionadas às características do concreto. Esses dados podem fornecer informações importantes para o acompanhamento da qualidade, a identificação de possíveis problemas e o apoio à tomada de decisões técnicas.

Entretanto, antes da realização de qualquer análise estatística, é necessário verificar a qualidade e a consistência das informações disponíveis. Em situações reais, bases de dados podem apresentar valores ausentes, erros de digitação, diferentes formas de registro de uma mesma categoria, problemas relacionados à utilização de vírgulas e pontos decimais, valores com ordem de grandeza inadequada e outras inconsistências. Dessa forma, o tratamento e a organização dos dados constituem etapas essenciais para garantir que as análises realizadas posteriormente sejam confiáveis e representem adequadamente o fenômeno estudado.

Neste relatório, será analisada uma base de dados relacionada ao controle tecnológico do concreto, composta por 100 observações e 10 variáveis que representam características como idade dos corpos de prova, resistência à compressão, consumo de cimento, relação água/cimento, abatimento, densidade e absorção de água dos agregados. A partir dessa base, serão realizadas etapas de inspeção, diagnóstico, organização, limpeza, transformação e exploração dos dados, buscando identificar possíveis inconsistências e avaliar a coerência das informações registradas.

Para o processamento da base, será utilizada a linguagem de programação R, com prioridade para os recursos da família tidyverse, especialmente os pacotes dplyr, tidyr, stringr, readr, purrr e ggplot2. A utilização dessas ferramentas permitirá estruturar um fluxo de tratamento dos dados de maneira organizada e reprodutível, desde a leitura da base original até a produção de informações e visualizações úteis para a análise.

Assim, o objetivo deste relatório é desenvolver uma abordagem prática de tratamento e exploração de dados aplicados à Engenharia Civil, demonstrando que a qualidade da análise depende não apenas dos métodos estatísticos empregados, mas também da identificação e do tratamento adequado dos problemas presentes nos dados. Ao final, pretende-se obter uma base organizada e consistente, capaz de fornecer informações relevantes para o acompanhamento do controle tecnológico do concreto e para a tomada de decisões no contexto da obra.

2 🎯 Objetivos

2.1 Objetivo geral

Realizar a inspeção, organização, limpeza, transformação e exploração de uma base de dados relacionada ao controle tecnológico do concreto, utilizando a linguagem R e, prioritariamente, as ferramentas da família tidyverse, de modo a identificar inconsistências, corrigir problemas nos registros e obter informações relevantes para a avaliação da qualidade do concreto.

2.2 Objetivos específicos

  • Inspecionar a estrutura da base de dados e identificar os tipos e características das variáveis disponíveis; Verificar a existência de valores ausentes, registros inconsistentes e possíveis erros de preenchimento ou digitação;

  • Identificar problemas relacionados a formatos numéricos, casas decimais, unidades e ordem de grandeza dos valores;

  • Padronizar variáveis categóricas e textuais, eliminando diferenças de formatação, espaços adicionais e formas distintas de representação;

  • Organizar e transformar os dados utilizando, prioritariamente, funções dos pacotes dplyr, tidyr, stringr, readr e purrr;

  • Criar uma versão tratada da base de dados, denominada dados_limpos, preservando a base original para fins de comparação e rastreabilidade;

  • Explorar as características dos dados por meio de medidas estatísticas e representações gráficas;

  • Utilizar o ggplot2 para produzir visualizações que auxiliem na identificação de padrões, tendências e possíveis anomalias nos dados;

  • Avaliar a coerência dos registros relacionados às propriedades do concreto, como resistência à compressão, relação água/cimento, abatimento e densidade;

  • Produzir informações que possam auxiliar o engenheiro responsável no acompanhamento do controle tecnológico e na tomada de decisões relacionadas à qualidade do concreto.


3 📚 Fundamentação Teórica

O processamento e a análise exploratória de dados deste relatório fundamentam-se no ecossistema tidyverse, que operacionaliza o ciclo da ciência de dados: importar, organizar, transformar e visualizar (Wickham, Çetinkaya-Rundel e Grolemund, 2023). As principais funções utilizadas para o tratamento da base de controle tecnológico do concreto, organizadas de acordo com as etapas do fluxo de trabalho.

Importação de Dados

A primeira etapa de qualquer análise é trazer os dados para o R. Para dados tabulares e retangulares, o pacote readr fornece funções otimizadas e rápidas (Wickham, Çetinkaya-Rundel e Grolemund, 2023).

  • read_csv2(): Função projetada especificamente para ler arquivos delimitados por ponto e vírgula (;), formato padrão em países onde a vírgula (,) é utilizada como separador decimal.

  • parse_double(): Uma função de conversão estrita que força o R a interpretar um vetor de caracteres como números reais (decimais), sendo vital quando erros de digitação forçam colunas numéricas a serem lidas como texto.

Transformação de Dados

O pacote dplyr fornece a gramática principal para a manipulação dos dados, operando através de verbos que resolvem a grande maioria dos desafios de transformação (Wickham, Çetinkaya-Rundel e Grolemund, 2023).

  • filter(): Seleciona um subconjunto de linhas com base em condições lógicas (por exemplo, abatimento_mm > 300). É a ferramenta principal para isolar valores incompatíveis na base.

  • select(): Reduz a base de dados mantendo apenas as colunas (variáveis) de interesse. Trabalha em conjunto com funções auxiliares de seleção, como everything() (todas as colunas), where(is.numeric) (apenas colunas de um tipo específico) e all_of() (seleção baseada em um vetor externo de strings).

  • mutate(): Cria novas colunas ou modifica colunas existentes operando linha por linha. Foi utilizado para criar as variáveis derivadas de classificação e corrigir grandezas deslocadas.

  • group_by() e summarise(): A combinação essencial para agregações. O group_by() altera o escopo das funções seguintes para operarem por subgrupos (como tipo_concreto), enquanto o summarise() reduz cada grupo a uma única linha de resumo estatístico (calculando mean(), sd(), median(), min() e max()).

  • arrange(): Altera a ordem das linhas, permitindo ranquear os resultados, frequentemente auxiliado pela função auxiliar desc() para forçar a ordem decrescente.

Vetores Lógicos e Números

Operações condicionais são necessárias para limpar dados sem afetar a base inteira (Wickham, Çetinkaya-Rundel e Grolemund, 2023).

  • if_else(): Avalia uma condição lógica vetorizada, retornando um valor se for verdadeira e outro se for falsa. Utilizado para dividir valores de abatimento superestimados de forma condicional.

  • case_when(): Uma generalização do if_else() para múltiplas condições aninhadas. Permite classificar os corpos de prova em “Conforme”, “Atenção” ou “Não Conforme” com uma sintaxe limpa.

Strings e Expressões Regulares

Na prática, dados textuais frequentemente apresentam inconsistências e o pacote stringr é utilizado para higienizá-los (Wickham, Çetinkaya-Rundel e Grolemund, 2023).

  • str_detect(): Retorna um vetor lógico indicando se um padrão textual foi encontrado na string. Fundamental para encontrar caracteres intrusos em colunas numéricas.

  • str_replace_all(): Substitui todas as ocorrências de um padrão por outro. Permitiu trocar vírgulas por pontos e letras por zeros antes da conversão.

  • str_trim(): Remove espaços em branco indesejados no início ou no final do texto, corrigindo erros de digitação invisíveis em categorias textuais.

  • str_to_upper(): Padroniza todos os caracteres para letras maiúsculas, unificando categorias digitadas de formas diferentes.

  • Expressões Regulares (Regex): Linguagem concisa para descrever padrões em strings. O uso do padrão [^0-9.] exemplifica o poder das regex para encontrar anomalias nos dados numéricos de forma universal.

Valores Faltantes

A ausência de informação requer tratamento explícito no R (Wickham, Çetinkaya-Rundel e Grolemund, 2023).

  • is.na(): Identifica se um valor é estruturalmente ausente (NA). É utilizado em conjunto com os filtros textuais e lógicos para diagnosticar perdas de dados sem quebrar as funções matemáticas.

Iteração e Operações em Colunas

Para evitar repetição exaustiva de código ao aplicar a mesma transformação matemática a múltiplas propriedades físicas, utilizamos as ferramentas de iteração do dplyr (Wickham, Çetinkaya-Rundel e Grolemund, 2023).

  • across(): Permite aplicar uma função (ou uma lista de funções) a múltiplas colunas simultaneamente. Utilizado dentro de mutate() para conversões em massa e dentro de summarise() para gerar estatísticas descritivas de todas as propriedades físicas de uma só vez.

Visualização de Dados

A análise exploratória visual no R é dominada pelo pacote ggplot2, que implementa a gramática dos gráficos através de camadas (Wickham, Çetinkaya-Rundel e Grolemund, 2023).

  • ggplot(): Inicializa o gráfico e define os mapeamentos estéticos principais através da função auxiliar aes(), como os eixos x e y.

  • geom_*(): Definem a representação visual dos dados. O geom_boxplot() revela a distribuição, mediana e outliers da resistência por tipo de concreto. O geom_point() gera gráficos de dispersão para investigar relações contínuas (tendências), como o impacto do consumo de cimento na resistência final.


4 ⚙️ Metodologia

A metodologia foi desenvolvida a partir de uma base contendo 100 observações e 10 variáveis relacionadas ao controle tecnológico do concreto. O processamento foi realizado no software R, utilizando principalmente ferramentas da família tidyverse.

Inicialmente, foi realizada a inspeção da estrutura da base, verificando os tipos das variáveis, valores ausentes e possíveis inconsistências. Em seguida, foram investigados erros de digitação, diferenças na escrita das categorias, valores com ordem de grandeza inadequada e problemas na representação de dados numéricos.

Após o diagnóstico, foi criada uma cópia denominada dados_limpos, preservando a base original. Foram realizadas correções e padronizações utilizando funções dos pacotes dplyr, stringr e readr, incluindo a conversão de variáveis para o formato numérico, correção de caracteres e padronização das categorias.

Por fim, os dados tratados foram explorados por meio de estatísticas descritivas e gráficos elaborados com ggplot2, permitindo analisar o comportamento da resistência do concreto e sua relação com outras características da base.


5 🔍 Resultados e Discussão

Os resultados obtidos a partir do processamento da base de dados são apresentados e discutidos a seguir, considerando as etapas necessárias. Inicialmente, realizou-se a inspeção e caracterização da base, buscando compreender sua estrutura, suas variáveis e a forma como os dados foram interpretados pelo software R. Em seguida, foram investigadas possíveis inconsistências, valores ausentes e registros potencialmente incompatíveis com o contexto analisado. Após essa etapa de diagnóstico, procedeu-se à limpeza e transformação dos dados, permitindo sua utilização nas análises estatísticas e na elaboração das representações gráficas. Dessa forma, a apresentação dos resultados acompanha a sequência metodológica adotada no código desenvolvido, destacando não apenas os valores obtidos, mas também a interpretação dos resultados e a justificativa das decisões tomadas durante o processamento.

A base de dados reúne informações relacionadas ao controle tecnológico do concreto, permitindo analisar diferentes características dos corpos de prova e das condições em que os ensaios foram realizados, conforme definições a seguir:

  • id_corpo_prova (identificação do corpo de prova)
  • obra (Bloco da obra onde ocorreu a concretagem)
  • tipo_concreto (Classe do Concreto)
  • idade_dias (Idade do corpo de prova no momento do ensaio)
  • resistencia_mpa(Resistência à compressão em MPa)
  • cimento_kg_m3(Consumo de cimento em kg/m³)
  • relacao_a_c (relação água/cimento)
  • abatimento_mm (abatimento do concreto, em mm)
  • densidade_kg_m3(densidade aparente do concreto, em kg/m³)
  • absorção_agregado_pct (Absorção de água do agregado, em %).

5.1 Conhecendo a base de dados

Inicialmente, foi realizada a importação da base de dados para o ambiente R utilizando recursos da família tidyverse, conforme proposto na atividade. A leitura foi realizada por meio da função read_delim(), considerando o ponto como separador decimal e o ponto e vírgula como delimitador das colunas. A utilização dessa configuração permitiu a leitura da base sem a necessidade de alterações no arquivo original.

A inspeção inicial, realizada por meio das funções head() e tail(), permitiu verificar, respectivamente, as primeiras e as últimas observações da base. Observou-se que os registros estão organizados de forma tabular, sendo cada linha correspondente a um corpo de prova e cada coluna associada a uma característica do concreto. Os identificadores dos corpos de prova seguem uma sequência de CP-001 a CP-100, indicando que não foram observadas falhas aparentes na sequência dos registros.

Código
library(tidyverse) # Carregamento dos pacotes da família tidyverse

# Importação da base de dados
dados <- read_delim(
  "base_processamento_dados_engenharia_civil.csv",
  delim = ";",
  locale = locale(decimal_mark = "."),
  show_col_types = FALSE
)

head(dados) # Visualiza as primeiras linhas 
# A tibble: 6 × 10
  id_corpo_prova obra    tipo_concreto idade_dias resistencia_mpa cimento_kg_m3
  <chr>          <chr>   <chr>              <dbl> <chr>           <chr>        
1 CP-001         Bloco A C35                   28 36.3            395          
2 CP-002         Bloco A C30                    7 28.4            340          
3 CP-003         Bloco C C30                   56 36.1            338          
4 CP-004         Bloco A C40                   28 47.2            407          
5 CP-005         Bloco B C25                   28 27.9            316          
6 CP-006         Bloco B C40                   28 41.5            398          
# ℹ 4 more variables: relacao_a_c <chr>, abatimento_mm <dbl>,
#   densidade_kg_m3 <dbl>, absorção_agregado_pct <dbl>
Código
tail(dados) # Visualiza as útlimas linhas
# A tibble: 6 × 10
  id_corpo_prova obra    tipo_concreto idade_dias resistencia_mpa cimento_kg_m3
  <chr>          <chr>   <chr>              <dbl> <chr>           <chr>        
1 CP-095         Bloco A C25                   28 30.3            327          
2 CP-096         Bloco D C25                    7 21.3            295          
3 CP-097         Bloco A C25                   28 26.7            356          
4 CP-098         Bloco A C35                   14 37.0            375          
5 CP-099         Bloco C C25                   56 31.1            332          
6 CP-100         Bloco A C30                   56 30.9            377          
# ℹ 4 more variables: relacao_a_c <chr>, abatimento_mm <dbl>,
#   densidade_kg_m3 <dbl>, absorção_agregado_pct <dbl>
Código
cat("\nO número de observações e variáveis existentes na base de dados são: \n")

O número de observações e variáveis existentes na base de dados são: 
Código
dim (dados) # Número de observações e variáveis existentes na base
[1] 100  10

A aplicação da função dim() indicou que a base possui 100 observações e 10 variáveis. Portanto, a estrutura inicial contém informações referentes a 100 registros de controle tecnológico do concreto, distribuídos entre variáveis de identificação, classificação e propriedades físicas e mecânicas.

A função glimpse() permitiu analisar de forma detalhada a estrutura da base de dados e verificar os tipos atribuídos pelo R às diferentes variáveis.

Código
glimpse(dados) # Estrutura da base
Rows: 100
Columns: 10
$ id_corpo_prova        <chr> "CP-001", "CP-002", "CP-003", "CP-004", "CP-005"…
$ obra                  <chr> "Bloco A", "Bloco A", "Bloco C", "Bloco A", "Blo…
$ tipo_concreto         <chr> "C35", "C30", "C30", "C40", "C25", "C40", "C25",…
$ idade_dias            <dbl> 28, 7, 56, 28, 28, 28, 56, 28, 14, 7, 7, 28, 28,…
$ resistencia_mpa       <chr> "36.3", "28.4", "36.1", "47.2", "27.9", "41.5", …
$ cimento_kg_m3         <chr> "395", "340", "338", "407", "316", "398", "351",…
$ relacao_a_c           <chr> "0.5", "0.54", "0.56", "0.47", "0.61", "0.43", "…
$ abatimento_mm         <dbl> 111, 114, 106, 142, 133, 98, 99, 116, 125, 127, …
$ densidade_kg_m3       <dbl> 2332, 2389, 2427, 2345, 2448, 2324, 2385, 2387, …
$ absorção_agregado_pct <dbl> 2.30, 1.85, 1.89, 1.97, 2.31, 0.80, 1.18, 1.33, …

Conforme observado, as variáveis id_corpo_prova, obra e tipo_concreto foram reconhecidas como caracteres (<chr>), por apresentarem informações de identificação e classificação. A variável idade_dias foi identificada como numérica (), assim como abatimento_mm, densidade_kg_m3 e absorção_agregado_pct. Por outro lado, as variáveis resistencia_mpa, cimento_kg_m3 e relacao_a_c, embora representem informações quantitativas, foram inicialmente interpretadas pelo R como caracteres (<chr>). Esse resultado indica a existência de possíveis inconsistências na forma de registro desses dados, que deverão ser investigadas nas etapas posteriores, especialmente quanto à representação dos valores numéricos e à necessidade de conversão para o tipo adequado.

A análise dos tipos das variáveis, realizada por meio da função glimpse(), mostrou que o R reconheceu quatro variáveis como quantitativas (): idade_dias, abatimento_mm, densidade_kg_m3 e absorção_agregado_pct. As demais foram identificadas como variáveis de caracteres (), sendo elas id_corpo_prova, obra, tipo_concreto, resistencia_mpa, cimento_kg_m3 e relacao_a_c. Entretanto, a classificação obtida pelo R não corresponde integralmente à natureza das variáveis no contexto da Engenharia Civil. As variáveis resistencia_mpa, cimento_kg_m3 e relacao_a_c representam grandezas quantitativas, mas foram armazenadas como texto na base de dados.

  • Resumo das Variáveis (summary())
Código
dados |> summary() # resumo das variáveis
   id_corpo_prova        obra       tipo_concreto   idade_dias 
 Length   :100    Length   :100   Length   :100   Min.   :  7  
 N.unique :100    N.unique :  5   N.unique :  5   1st Qu.: 14  
 N.blank  :  0    N.blank  :  0   N.blank  :  0   Median : 28  
 Min.nchar:  6    Min.nchar:  7   Min.nchar:  3   Mean   : 28  
 Max.nchar:  6    Max.nchar:  8   Max.nchar:  3   3rd Qu.: 28  
                                                  Max.   :280  
                                                               
  resistencia_mpa   cimento_kg_m3    relacao_a_c  abatimento_mm   
 Length   :100    Length   :100   Length   :100   Min.   :  64.0  
 N.unique : 83    N.unique : 68   N.unique : 24   1st Qu.:  99.5  
 N.blank  :  0    N.blank  :  0   N.blank  :  0   Median : 110.0  
 Min.nchar:  4    Min.nchar:  3   Min.nchar:  3   Mean   : 121.7  
 Max.nchar:  4    Max.nchar:  4   Max.nchar:  4   3rd Qu.: 122.5  
 NAs      :  1                    NAs      :  1   Max.   :1250.0  
                                                  NAs    :1       
 densidade_kg_m3 absorção_agregado_pct
 Min.   : 238    Min.   : 0.800       
 1st Qu.:2348    1st Qu.: 1.475       
 Median :2374    Median : 1.850       
 Mean   :2351    Mean   : 1.953       
 3rd Qu.:2388    3rd Qu.: 2.110       
 Max.   :2464    Max.   :18.400       
 NAs    :1       NAs    :1            
Código
# Visualização dos nomes das variáveis.
names(dados)
 [1] "id_corpo_prova"        "obra"                  "tipo_concreto"        
 [4] "idade_dias"            "resistencia_mpa"       "cimento_kg_m3"        
 [7] "relacao_a_c"           "abatimento_mm"         "densidade_kg_m3"      
[10] "absorção_agregado_pct"

O resumo das variáveis, obtido por meio da função summary(), permitiu identificar as principais características descritivas da base e a presença de valores ausentes. A variável idade_dias apresentou valores entre 7 e 280 dias, com mediana e média de 28 dias, respectivamente. Para resistencia_mpa, foram identificados 83 valores distintos e 1 valor ausente, enquanto cimento_kg_m3 apresentou 68 valores distintos e relacao_a_c, 24 valores distintos, ambas sem valores ausentes. Entre as variáveis numéricas, abatimento_mm apresentou valores entre 64 e 1250 mm, com média de 121,7 mm, e densidade_kg_m3 variou de 238 a 2464 kg/m³, com média de 2351 kg/m³. A variável absorção_agregado_pct apresentou valores entre 0,8% e 18,4%, com média de 1,953%, também com um valor ausente. Esses resultados permitem observar, ainda na análise inicial, a existência de valores que apresentam grande dispersão ou magnitude discrepante em relação aos demais registros, os quais deverão ser investigados nas etapas seguintes. Além disso, conforme verificado anteriormente pela função glimpse(), as variáveis resistencia_mpa, cimento_kg_m3 e relacao_a_c foram interpretadas pelo R como caracteres (<chr>), apesar de representarem informações quantitativas, indicando a necessidade de posterior verificação e tratamento dos registros.

  • Valores Ausentes

Antes de prosseguir, é importante verificar a existência de valores ausentes (NA) na base de dados, uma vez que sua presença pode comprometer a realização de análises posteriores e influenciar a interpretação dos resultados. Para isso, foram utilizados recursos do tidyverse para quantificar os valores ausentes em cada variável e, posteriormente, identificar quais observações apresentam registros incompletos. Essa análise permite avaliar a extensão dos dados faltantes e localizar os registros que deverão ser considerados nas etapas de tratamento e limpeza da base.

Código
cat("\nA quantidade de valores ausentes em cada variável existente na base de dados é: \n")

A quantidade de valores ausentes em cada variável existente na base de dados é: 
Código
# Quantidade de valores ausentes por variável:
dados |>
  summarise( 
    across(
      everything(),
      ~ sum(is.na(.x))
    )
  ) |>
print(width = Inf)
# A tibble: 1 × 10
  id_corpo_prova  obra tipo_concreto idade_dias resistencia_mpa cimento_kg_m3
           <int> <int>         <int>      <int>           <int>         <int>
1              0     0             0          0               1             0
  relacao_a_c abatimento_mm densidade_kg_m3 absorção_agregado_pct
        <int>         <int>           <int>                 <int>
1           1             1               1                     1
Código
# summarise(): Reduz a base de dados a um resumo estatístico (neste caso, a soma de NAs).
# across(): Permite aplicar a mesma função a múltiplas colunas simultaneamente.
# everything(): Seleciona todas as colunas da base.
# is.na(): Retorna TRUE se o valor for NA (ausente). A soma de TRUEs equivale à contagem de NAs.

cat("\nAs observações onde contêm valores ausentes são: \n")

As observações onde contêm valores ausentes são: 
Código
# Em quais observações aparecem NA
dados |>
  filter(if_any(everything(), is.na)
  ) |>
print(width = Inf)
# A tibble: 5 × 10
  id_corpo_prova obra    tipo_concreto idade_dias resistencia_mpa cimento_kg_m3
  <chr>          <chr>   <chr>              <dbl> <chr>           <chr>        
1 CP-015         Bloco B C35                   14 36.3            363          
2 CP-038         Bloco C C25                   28 25.7            309          
3 CP-077         Bloco D C25                   14 19.0            307          
4 CP-092         Bloco B C35                   14 <NA>            370          
5 CP-097         Bloco A C25                   28 26.7            356          
  relacao_a_c abatimento_mm densidade_kg_m3 absorção_agregado_pct
  <chr>               <dbl>           <dbl>                 <dbl>
1 0.49                   NA            2359                  1.93
2 <NA>                  146            2334                  2.12
3 0.63                  119              NA                  1.38
4 0.47                  111            2380                  2.38
5 0.64                  122            2440                 NA   
Código
# filter(): Filtra as linhas da base de dados segundo uma condição lógica.
# if_any(): Verifica se a condição (is.na) é verdadeira para 'qualquer' uma das colunas selecionadas (everything()).

De modo geral, a primeira inspeção demonstrou que a base possui uma estrutura organizada, porém não está completamente pronta para a aplicação de análises estatísticas. A identificação das diferenças entre os tipos de dados, dos valores ausentes e das inconsistências nas categorias é fundamental antes da realização dos cálculos e gráficos. Dessa forma, os resultados da Etapa 1 justificam a necessidade das etapas seguintes de investigação, limpeza e transformação dos dados, evitando que erros de registro sejam interpretados como características reais do concreto.

5.2 Investigação da qualidade e consistência dos dados

Após a caracterização inicial da base de dados, iniciou-se a investigação de possíveis problemas de qualidade e consistência dos registros. Nessa fase, buscou-se verificar se os valores presentes na base são compatíveis com o contexto do controle tecnológico do concreto, identificando situações que possam representar erros de digitação, registros inadequados ou valores potencialmente discrepantes.

Nesse processo, foram utilizados principalmente recursos do dplyr, como filter(), select(), count() e distinct(), permitindo localizar e examinar as observações que apresentaram características potencialmente incompatíveis ou inconsistentes. A análise também contemplou a verificação da padronização das categorias das variáveis qualitativas, especialmente obra e tipo_concreto, uma vez que diferentes formas de escrita podem fazer com que registros pertencentes ao mesmo grupo sejam interpretados como categorias distintas pelo R.

Desta forma, inicialmente, analisou-se possíveis erros de digitação (presença de caracteres em dados quantitativos), retornando o seguinte resultado:

Código
# QUESTAO 8: Analisando erros de digitação
# filter(): Seleciona as observações (linhas) suspeitas.
# if_any(): Varre múltiplas colunas verificando se 'qualquer' uma contém o erro.
# -(1:3): Exclui as 3 primeiras colunas (id, obra, tipo) da varredura, pois 
#         estas são categóricas e naturalmente contêm letras e hifens.
# str_detect(): Função do pacote stringr que avalia a presença do padrão Regex.
# "[^0-9.]": O acento circunflexo (^) nega a busca. Logo, procura tudo que NÃO é dígito/ponto.
# !is.na(.x): Garante que a função ignore os NAs.
# select(): Usamos everything() para atender ao requisito de apresentar o registro completo.
dados |>
  filter(
    if_any(
      -(1:3), 
      ~ str_detect(as.character(.x), "[^0-9.]") & !is.na(.x)
    )
  ) |>
  select(everything())
# A tibble: 4 × 10
  id_corpo_prova obra    tipo_concreto idade_dias resistencia_mpa cimento_kg_m3
  <chr>          <chr>   <chr>              <dbl> <chr>           <chr>        
1 CP-008         Bloco D C30                   28 38,7            347          
2 CP-019         Bloco B C30                   28 3O,4            356          
3 CP-045         Bloco C C40                   14 42.9            407          
4 CP-064         Bloco A C30                    7 25.6            390O         
# ℹ 4 more variables: relacao_a_c <chr>, abatimento_mm <dbl>,
#   densidade_kg_m3 <dbl>, absorção_agregado_pct <dbl>

Para verificar a existência de valores potencialmente incompatíveis com o contexto da Engenharia Civil, foram estabelecidos critérios de triagem para as principais variáveis analisadas. Foram selecionados registros com idade_dias superior a 100 dias, abatimento_mm superior a 300 mm, densidade_kg_m3 inferior a 2000 kg/m³ ou absorção_agregado_pct superior a 10%. Para as variáveis resistencia_mpa e relacao_a_c, foi realizada uma conversão temporária dos valores, com correção de possíveis registros contendo a letra “O” no lugar do algarismo “0” e substituição da vírgula pelo ponto decimal, permitindo verificar se os valores numéricos resultantes ultrapassavam os limites de 100 MPa e 1,5, respectivamente. Dessa forma, o procedimento permitiu identificar registros que apresentavam valores que merecem investigação mais detalhada, sem alterar, neste momento, os dados originais da base.

# A tibble: 4 × 6
  id_corpo_prova idade_dias resistencia_mpa abatimento_mm densidade_kg_m3
  <chr>               <dbl> <chr>                   <dbl>           <dbl>
1 CP-032                 14 36.6                     1250            2383
2 CP-053                 28 27.4                       97             238
3 CP-072                 14 37.3                       98            2414
4 CP-085                280 38.3                      141            2377
# ℹ 1 more variable: absorção_agregado_pct <dbl>

Após a análise dos possíveis valores incompatíveis, foi realizada a verificação das variáveis qualitativas, com o objetivo de identificar inconsistências na padronização das categorias. Essa etapa é importante porque diferenças na forma de escrita, como espaços adicionais ou variações entre letras maiúsculas e minúsculas, podem fazer com que o R interprete registros pertencentes a uma mesma categoria como grupos distintos. Inicialmente, a variável obra foi investigada por meio das funções count() e distinct(), complementadas pela identificação de registros com espaços adicionais. Em seguida, foi analisada a variável tipo_concreto, utilizando distinct() para verificar todas as categorias presentes e identificar possíveis formas diferentes de representação de uma mesma classe de concreto.

# A tibble: 5 × 2
  obra           n
  <chr>      <int>
1 "Bloco A"     28
2 "Bloco B"     28
3 "Bloco B "     1
4 "Bloco C"     28
5 "Bloco D"     15
# A tibble: 5 × 1
  obra      
  <chr>     
1 "Bloco A" 
2 "Bloco C" 
3 "Bloco B" 
4 "Bloco D" 
5 "Bloco B "
# A tibble: 1 × 10
  id_corpo_prova obra     tipo_concreto idade_dias resistencia_mpa cimento_kg_m3
  <chr>          <chr>    <chr>              <dbl> <chr>           <chr>        
1 CP-027         "Bloco … C30                   28 39.4            365          
# ℹ 4 more variables: relacao_a_c <chr>, abatimento_mm <dbl>,
#   densidade_kg_m3 <dbl>, absorção_agregado_pct <dbl>
# A tibble: 5 × 1
  tipo_concreto
  <chr>        
1 C35          
2 C30          
3 C40          
4 C25          
5 c30          
Rows: 100
Columns: 10
$ id_corpo_prova        <chr> "CP-001", "CP-002", "CP-003", "CP-004", "CP-005"…
$ obra                  <chr> "Bloco A", "Bloco A", "Bloco C", "Bloco A", "Blo…
$ tipo_concreto         <chr> "C35", "C30", "C30", "C40", "C25", "C40", "C25",…
$ idade_dias            <dbl> 28, 7, 56, 28, 28, 28, 56, 28, 14, 7, 7, 28, 28,…
$ resistencia_mpa       <chr> "36.3", "28.4", "36.1", "47.2", "27.9", "41.5", …
$ cimento_kg_m3         <chr> "395", "340", "338", "407", "316", "398", "351",…
$ relacao_a_c           <chr> "0.5", "0.54", "0.56", "0.47", "0.61", "0.43", "…
$ abatimento_mm         <dbl> 111, 114, 106, 142, 133, 98, 99, 116, 125, 127, …
$ densidade_kg_m3       <dbl> 2332, 2389, 2427, 2345, 2448, 2324, 2385, 2387, …
$ absorção_agregado_pct <dbl> 2.30, 1.85, 1.89, 1.97, 2.31, 0.80, 1.18, 1.33, …

A inspeção das categorias qualitativas também revelou algumas particularidades. Na variável obra, foram encontradas cinco categorias distintas, sendo quatro delas aparentemente padronizadas e uma apresentada como “Bloco B ”, contendo espaço adicional ao final do texto. Na variável tipo_concreto, também foram identificadas cinco categorias, embora a base tenha como classes esperadas C25, C30, C35 e C40. A ocorrência de “c30”, em letras minúsculas, indica uma inconsistência de padronização que deverá ser corrigida durante a etapa de limpeza. A necessidade desse tipo de verificação está de acordo com os problemas previstos na atividade, que incluem diferenças na escrita das categorias e espaços adicionais.

5.3 Limpeza e transformação da base de dados

Após a identificação dos possíveis problemas e inconsistências presentes na base, iniciou-se a terceira etapa, destinada à limpeza e transformação dos dados. O objetivo dessa fase foi produzir uma versão da base adequada às análises posteriores, realizando as correções necessárias sem modificar diretamente os dados originais. Para isso, foi criada uma cópia denominada dados_limpos, sobre a qual foram aplicados os procedimentos de padronização das variáveis qualitativas, conversão das variáveis quantitativas para os tipos adequados e tratamento dos valores ausentes. Dessa maneira, buscou-se garantir maior consistência e confiabilidade aos dados antes da realização das análises estatísticas.

Rows: 100
Columns: 10
$ id_corpo_prova        <chr> "CP-001", "CP-002", "CP-003", "CP-004", "CP-005"…
$ obra                  <chr> "Bloco A", "Bloco A", "Bloco C", "Bloco A", "Blo…
$ tipo_concreto         <chr> "C35", "C30", "C30", "C40", "C25", "C40", "C25",…
$ idade_dias            <dbl> 28, 7, 56, 28, 28, 28, 56, 28, 14, 7, 7, 28, 28,…
$ resistencia_mpa       <dbl> 36.3, 28.4, 36.1, 47.2, 27.9, 41.5, 23.7, 38.7, …
$ cimento_kg_m3         <dbl> 395, 340, 338, 407, 316, 398, 351, 347, 346, 315…
$ relacao_a_c           <dbl> 0.50, 0.54, 0.56, 0.47, 0.61, 0.43, 0.65, 0.54, …
$ abatimento_mm         <dbl> 111, 114, 106, 142, 133, 98, 99, 116, 125, 127, …
$ densidade_kg_m3       <dbl> 2332, 2389, 2427, 2345, 2448, 2324, 2385, 2387, …
$ absorção_agregado_pct <dbl> 2.30, 1.85, 1.89, 1.97, 2.31, 0.80, 1.18, 1.33, …

A criação de uma cópia da base original, denominada dados_limpos, tem por objetivo realizar os procedimentos de tratamento sem alterar os dados inicialmente importados. Essa decisão é importante porque preservar a base original permite manter os registros brutos como referência, possibilitando comparar os dados antes e depois do tratamento, revisar eventuais decisões de correção e evitar a perda das informações originalmente fornecidas. Assim, qualquer alteração realizada durante o processamento pode ser rastreada e, caso necessário, revisada.

Na sequência, foram padronizadas as variáveis qualitativas. Na variável obra, foram removidos espaços adicionais por meio de str_trim(). Para tipo_concreto, além da remoção de espaços, foram convertidas as letras para maiúsculas com str_to_upper() e eliminados os hífens por meio de str_replace_all(), permitindo uniformizar categorias como c30 e C-30 para uma mesma representação, C30.

Posteriormente, foi realizada a conversão das variáveis quantitativas que haviam sido inicialmente reconhecidas como caracteres. Com o uso de across() e funções de tratamento textual do stringr, foram corrigidas possíveis ocorrências da letra “O” no lugar do algarismo “0” e substituídas as vírgulas por pontos antes da conversão para valores numéricos. Após essa conversão, foram aplicadas correções específicas às variáveis que apresentavam casas decimais ou ordens de grandeza deslocadas. Os valores de abatimento_mm superiores a 300 foram divididos por 10; valores de densidade_kg_m3 inferiores a 1000 foram multiplicados por 10; valores de absorção_agregado_pct superiores a 10 foram divididos por 10; e valores de idade_dias superiores a 200 foram divididos por 10. Essas transformações tiveram como finalidade recuperar a grandeza considerada adequada para cada variável, com base nos problemas identificados na etapa anterior.

Ao final do procedimento, o glimpse(dados_limpos) mostrou que as variáveis quantitativas passaram a ser reconhecidas pelo R como numéricas (<dbl>), enquanto id_corpo_prova, obra e tipo_concreto permaneceram como variáveis de caracteres (<chr>). Dessa forma, a base passou a apresentar uma estrutura mais adequada para as etapas seguintes de análise e exploração dos dados.

  • Identificação e tratamento dos valores ausentes
# A tibble: 5 × 10
  id_corpo_prova obra    tipo_concreto idade_dias resistencia_mpa cimento_kg_m3
  <chr>          <chr>   <chr>              <dbl>           <dbl>         <dbl>
1 CP-015         Bloco B C35                   14            36.3           363
2 CP-038         Bloco C C25                   28            25.7           309
3 CP-077         Bloco D C25                   14            19             307
4 CP-092         Bloco B C35                   14            NA             370
5 CP-097         Bloco A C25                   28            26.7           356
# ℹ 4 more variables: relacao_a_c <dbl>, abatimento_mm <dbl>,
#   densidade_kg_m3 <dbl>, absorção_agregado_pct <dbl>

Após uma nova verificação dos valores ausentes o resultado identificou cinco registros contendo valores ausentes, correspondentes aos corpos de prova CP-015, CP-038, CP-077, CP-092 e CP-097. Os valores ausentes ocorreram, respectivamente, em diferentes variáveis da base: abatimento_mm no CP-015, relacao_a_c no CP-038, densidade_kg_m3 no CP-077, resistencia_mpa no CP-092 e absorção_agregado_pct no CP-097.

Diante desses registros, optou-se por manter os valores ausentes (NA) na base, não sendo realizada a exclusão das observações nem a substituição dos valores por estimativas, como a média. Essa decisão foi adotada porque o preenchimento de uma informação não registrada poderia introduzir um valor artificial e interferir na interpretação dos resultados. Além disso, a ausência de uma variável não implica necessariamente que todas as demais informações daquele corpo de prova sejam inválidas. Dessa forma, os registros serão preservados e os valores disponíveis poderão continuar sendo utilizados nas análises em que forem pertinentes, enquanto os NA deverão ser considerados pelos procedimentos estatísticos que envolvam especificamente as variáveis com dados ausentes.

A opção por consultar a fonte original dos dados também seria uma alternativa adequada para situações em que fosse possível recuperar os registros faltantes. Entretanto, considerando o procedimento adotado nesta atividade, não foi realizada essa recuperação, mantendo-se os NA para preservar a informação efetivamente disponível na base.

--- Estrutura (Glimpse) ---
Rows: 100
Columns: 10
$ id_corpo_prova        <chr> "CP-001", "CP-002", "CP-003", "CP-004", "CP-005"…
$ obra                  <chr> "Bloco A", "Bloco A", "Bloco C", "Bloco A", "Blo…
$ tipo_concreto         <chr> "C35", "C30", "C30", "C40", "C25", "C40", "C25",…
$ idade_dias            <dbl> 28, 7, 56, 28, 28, 28, 56, 28, 14, 7, 7, 28, 28,…
$ resistencia_mpa       <dbl> 36.3, 28.4, 36.1, 47.2, 27.9, 41.5, 23.7, 38.7, …
$ cimento_kg_m3         <dbl> 395, 340, 338, 407, 316, 398, 351, 347, 346, 315…
$ relacao_a_c           <dbl> 0.50, 0.54, 0.56, 0.47, 0.61, 0.43, 0.65, 0.54, …
$ abatimento_mm         <dbl> 111, 114, 106, 142, 133, 98, 99, 116, 125, 127, …
$ densidade_kg_m3       <dbl> 2332, 2389, 2427, 2345, 2448, 2324, 2385, 2387, …
$ absorção_agregado_pct <dbl> 2.30, 1.85, 1.89, 1.97, 2.31, 0.80, 1.18, 1.33, …

--- Resumo Estatístico ---
   id_corpo_prova        obra       tipo_concreto   idade_dias   
 Length   :100    Length   :100   Length   :100   Min.   : 7.00  
 N.unique :100    N.unique :  4   N.unique :  4   1st Qu.:14.00  
 N.blank  :  0    N.blank  :  0   N.blank  :  0   Median :28.00  
 Min.nchar:  6    Min.nchar:  7   Min.nchar:  3   Mean   :25.48  
 Max.nchar:  6    Max.nchar:  7   Max.nchar:  3   3rd Qu.:28.00  
                                                  Max.   :56.00  
                                                                 
 resistencia_mpa cimento_kg_m3    relacao_a_c     abatimento_mm  
 Min.   :19.00   Min.   :295.0   Min.   :0.4300   Min.   : 64.0  
 1st Qu.:28.75   1st Qu.:339.5   1st Qu.:0.5100   1st Qu.: 99.5  
 Median :32.30   Median :354.0   Median :0.5600   Median :110.0  
 Mean   :33.55   Mean   :357.6   Mean   :0.5537   Mean   :110.3  
 3rd Qu.:38.35   3rd Qu.:385.0   3rd Qu.:0.6000   3rd Qu.:122.5  
 Max.   :47.50   Max.   :418.0   Max.   :0.6500   Max.   :175.0  
 NAs    :1                       NAs    :1        NAs    :1      
 densidade_kg_m3 absorção_agregado_pct
 Min.   :2293    Min.   :0.800        
 1st Qu.:2348    1st Qu.:1.475        
 Median :2374    Median :1.840        
 Mean   :2373    Mean   :1.786        
 3rd Qu.:2388    3rd Qu.:2.100        
 Max.   :2464    Max.   :2.920        
 NAs    :1       NAs    :1            

Após a aplicação dos procedimentos de limpeza e transformação, a estrutura e o resumo estatístico da base foram novamente verificados por meio das funções glimpse() e summary().

As correções das grandezas produziram alterações importantes nos valores extremos. Na base original, foram identificados valores máximos de 280 dias para idade_dias, 1250 mm para abatimento_mm, 2464 kg/m³ para densidade_kg_m3 e 18,4% para absorção_agregado_pct, sendo alguns desses valores indicativos de possíveis erros de registro. Após a limpeza, os valores máximos passaram para 56 dias, 175 mm, 2464 kg/m³ e 2,92%, respectivamente. Essas alterações estão diretamente relacionadas às correções aplicadas durante o processamento, corrigindo registros para valores compatíveis com a ordem de grandeza esperada.

Após essas transformações, os valores mínimos e máximos apresentados pela base passaram a apresentar maior coerência com os demais registros de um conjunto de dados de controle tecnológico do concreto, indicando que os principais problemas de registro identificados nas etapas anteriores foram efetivamente tratados.

5.4 Exploração dos dados

Com a base dados_limpos devidamente estruturada e tratada, iniciou-se a etapa voltada à exploração e análise descritiva dos dados.


Resistência média dos Corpos de Prova:
# A tibble: 1 × 1
  resistencia_media_geral
                    <dbl>
1                    33.5

Resistência média à compressão agrupada por bloco da obra:
# A tibble: 4 × 2
  obra    resistencia_media
  <chr>               <dbl>
1 Bloco A              33.2
2 Bloco B              35.7
3 Bloco C              32.4
4 Bloco D              32.4

Resistência média agrupada por tipo de concreto:
# A tibble: 4 × 2
  tipo_concreto resistencia_media
  <chr>                     <dbl>
1 C25                        27.1
2 C30                        32.1
3 C35                        37.1
4 C40                        43.3

Resistência média à compressão agrupada por idade dos corpos de prova:
# A tibble: 4 × 2
  idade_dias resistencia_media
       <dbl>             <dbl>
1          7              28.8
2         14              34.7
3         28              34.7
4         56              33.1

Comparação do desempenho entre os blocos da obra
Para descobrir qual bloco teve o melhor e o pior desempenho, agrupamos por
obra, calculamos a média e ordenamos do maior para o menor.
# A tibble: 4 × 2
  obra    resistencia_media
  <chr>               <dbl>
1 Bloco B              35.7
2 Bloco A              33.2
3 Bloco D              32.4
4 Bloco C              32.4

Análise:
Ao observar o tibble gerado, o primeiro bloco da lista apresenta a maior
resistência média, enquanto o último apresenta a menor.

Análise de desempenho por Classe de Concreto
Verificação se os concretos com maior classe nominal (ex: C40) de fato
apresentaram a maior resistência média na prática.
# A tibble: 4 × 2
  tipo_concreto resistencia_media
  <chr>                     <dbl>
1 C40                        43.3
2 C35                        37.1
3 C30                        32.1
4 C25                        27.1

Análise:
A classe C40 deve encabeçar a lista por ter a maior resistência especificada.
A ordenação descrescente comprova se a hierarquia técnica (C40 > C35 > C30 > C25)
foi mantida durante a execução da obra.

Estatísticas médias das propriedades físicas por tipo de concreto
As principais variáveis tecnológicas foram agrupadas para interpretar como a dosagem
se comporta conforme a classe do concreto aumenta.
# A tibble: 4 × 6
  tipo_concreto media_resistencia media_cimento media_relacao_ac
  <chr>                     <dbl>         <dbl>            <dbl>
1 C40                        43.3          404.            0.478
2 C35                        37.1          378.            0.507
3 C30                        32.1          351.            0.568
4 C25                        27.1          323.            0.62 
# ℹ 2 more variables: media_abatimento <dbl>, media_densidade <dbl>

Interpretação Técnica dos Resultados:
- O consumo de cimento aumenta nas classes mais altas (C40) e a relação
  água/cimento diminui. Esse é o comportamento técnico correto e esperado,
  pois menos água e mais cimento aumentam a resistência da matriz.
- A densidade costuma se manter estável (em torno de 2350-2450 kg/m3),
  indicando que os agregados e o adensamento foram padronizados.

5.5 Criação de novas variáveis

Após a exploração das características da base por meio de estatísticas descritivas e agrupamentos, iniciou-se a etapa destinada à criação de novas variáveis a partir dos dados já tratados. Nessa etapa, utilizou-se principalmente a função mutate(), em conjunto com case_when() e outras operações do dplyr, para gerar informações derivadas que possibilitem uma interpretação mais aprofundada dos resultados.

As novas variáveis foram construídas com o propósito de relacionar a resistência observada dos corpos de prova com referências associadas às diferentes classes de concreto e, também, de classificar e comparar os registros segundo critérios definidos para a análise. Dessa forma, a utilização de variáveis derivadas permite ampliar as informações disponíveis na base sem modificar os dados originais, facilitando a identificação de padrões e a interpretação do desempenho dos corpos de prova

  • Variável Resistência Relativa: representa a razão entre a resistência observada e uma resistência de referência associada à classe do concreto.

A resistência de referência foi definida a partir da resistência característica (fck) correspondente à classe do concreto, utilizando diretamente o valor indicado na própria nomenclatura da classe. Assim, foram adotados 25 MPa para C25, 30 MPa para C30, 35 MPa para C35 e 40 MPa para C40. Essa referência foi utilizada posteriormente para calcular a resistência relativa de cada corpo de prova.

  • Variável Classificação: classifica os corpos de prova segundo um critério relacionado à resistência.

Os critérios de classificação foram definidos tomando como referência a resistência característica (fck) correspondente à classe de cada concreto. Os corpos de prova cuja resistência obtida foi maior ou igual à resistência de referência foram classificados como “Conforme”. Quando a resistência ficou até 10% abaixo da referência, adotou-se a classificação “Atenção”, indicando a necessidade de acompanhamento do resultado. Valores mais de 10% abaixo da referência foram classificados como “Não Conforme”, por representarem um afastamento mais significativo em relação ao valor de referência. Nos casos em que a resistência não estava disponível, adotou-se a categoria “Sem Dado”, evitando atribuir uma classificação sem informação suficiente.

Critérios técnicos definidos com base na resistência de referência:
- 'Conforme': Resistência obtida é maior ou igual à de referência.
- 'Atenção': Resistência caiu até 10% abaixo da referência.
- 'Não Conforme': Resistência caiu mais de 10% abaixo da referência (risco estrutural).
  • Variável acima_media: indica se a resistência do corpo de prova está acima ou abaixo da resistência média de seu respectivo tipo de concreto. A variável assume os seguintes valores: TRUE ou FALSE
Visualizando o resultado das novas variáveis criadas (primeiros registros):
# A tibble: 6 × 6
  id_corpo_prova tipo_concreto resistencia_mpa resistencia_relativa
  <chr>          <chr>                   <dbl>                <dbl>
1 CP-001         C35                      36.3                1.04 
2 CP-002         C30                      28.4                0.947
3 CP-003         C30                      36.1                1.20 
4 CP-004         C40                      47.2                1.18 
5 CP-005         C25                      27.9                1.12 
6 CP-006         C40                      41.5                1.04 
  classificacao acima_media
  <chr>         <lgl>      
1 Conforme      FALSE      
2 Atenção       FALSE      
3 Conforme      TRUE       
4 Conforme      TRUE       
5 Conforme      TRUE       
6 Conforme      FALSE      

5.6 Dados agrupados

  • Número de observações por Tipo de Concreto: quantidade de corpos de prova para cada classe de concreto
# A tibble: 4 × 2
  tipo_concreto quantidade_observacoes
  <chr>                          <int>
1 C25                               29
2 C30                               32
3 C35                               23
4 C40                               16
  • Resistência média de cada tipo de concreto ordenada em ordem decrescente
# A tibble: 4 × 2
  tipo_concreto resistencia_media
  <chr>                     <dbl>
1 C40                        43.3
2 C35                        37.1
3 C30                        32.1
4 C25                        27.1
  • Resumo Estatístico para os tipos de Concreto
# A tibble: 4 × 7
  tipo_concreto n_observacoes media mediana desvio_padrao minimo maximo
  <chr>                 <int> <dbl>   <dbl>         <dbl>  <dbl>  <dbl>
1 C25                      29  27.1    27.8          3.07   19     31.6
2 C30                      32  32.1    31.8          3.57   24.5   39.4
3 C35                      22  37.1    36.8          3.68   29.9   44.6
4 C40                      16  43.3    43.2          3.08   37.3   47.5

Uma tabela que apresenta várias estatísticas é mais informativa do que uma tabela contendo apenas a média porque permite avaliar não apenas o valor central dos resultados, mas também a variabilidade e a dispersão dos dados. Na Engenharia Civil, a média isolada pode ocultar diferenças importantes entre os corpos de prova. Por exemplo, uma classe de concreto pode apresentar média de resistência superior ao seu valor de referência, mas, ao mesmo tempo, possuir elevado desvio-padrão e valores mínimos significativamente inferiores. A análise conjunta da média, mediana, desvio-padrão, mínimo e máximo permite, portanto, avaliar melhor a uniformidade dos resultados e a ocorrência de valores extremos, proporcionando uma interpretação mais completa do comportamento da resistência do concreto e contribuindo para uma avaliação mais adequada do controle tecnológico.

5.7 Seleção e Organização de variáveis

As propriedades físicas correspondem às variáveis numéricas:

Visualização da nova tabela (apenas propriedades físicas):
# A tibble: 6 × 7
  idade_dias resistencia_mpa cimento_kg_m3 relacao_a_c abatimento_mm
       <dbl>           <dbl>         <dbl>       <dbl>         <dbl>
1         28            36.3           395        0.5            111
2          7            28.4           340        0.54           114
3         56            36.1           338        0.56           106
4         28            47.2           407        0.47           142
5         28            27.9           316        0.61           133
6         28            41.5           398        0.43            98
# ℹ 2 more variables: densidade_kg_m3 <dbl>, absorção_agregado_pct <dbl>

Questão 28: Média das variáveis quantitativas utilizando across()
# A tibble: 1 × 7
  idade_dias resistencia_mpa cimento_kg_m3 relacao_a_c abatimento_mm
       <dbl>           <dbl>         <dbl>       <dbl>         <dbl>
1       25.5            33.5          358.       0.554          110.
# ℹ 2 more variables: densidade_kg_m3 <dbl>, absorção_agregado_pct <dbl>

Comparação de abordagem: A utilização de across() torna o código mais simples e eficiente, pois evita a necessidade de utilizar summarise() individualmente para cada variável. Nesse caso, seria necessário escrever sete linhas de código, uma para cada variável analisada, enquanto o uso de across() permite realizar a mesma operação de forma conjunta. Essa abordagem também facilita a manutenção do código, especialmente quando o número de variáveis aumenta, como em bases contendo diversas propriedades obtidas em ensaios de laboratório.

Para atender à necessidade de realizar uma transformação simultânea nas variáveis quantitativas, foram criadas novas variáveis centralizadas em relação à média de cada propriedade. A transformação consiste em subtrair a média da respectiva variável de cada observação, permitindo identificar se determinado resultado está acima ou abaixo do comportamento médio da base. A utilização de mutate() em conjunto com across() possibilitou aplicar o procedimento simultaneamente às diferentes propriedades do concreto, sem alterar os valores originais.

# A tibble: 4 × 5
  tipo_concreto resistencia_mpa_media resistencia_mpa_dp abatimento_mm_media
  <chr>                         <dbl>              <dbl>               <dbl>
1 C25                            27.1               3.07                115.
2 C30                            32.1               3.57                111.
3 C35                            37.1               3.68                107.
4 C40                            43.3               3.08                105.
# ℹ 1 more variable: abatimento_mm_dp <dbl>

A utilização de across(), como observado acima, permite aplicar simultaneamente diferentes funções estatísticas às variáveis quantitativas, evitando a necessidade de escrever comandos separados para cada uma delas. Nesse caso, uma lista de funções pode ser fornecida ao across(), possibilitando obter, por exemplo, a média e o desvio-padrão de cada variável para cada tipo de concreto. Essa abordagem torna o código mais compacto, organizado e padronizado, além de facilitar sua manutenção quando novas variáveis forem acrescentadas à base. Comparativamente à elaboração de vários comandos individuais, o procedimento reduz a repetição do código e diminui a possibilidade de erros de digitação ou de aplicação inconsistente das mesmas operações entre as diferentes variáveis.

O uso de across() torna o procedimento mais eficiente, pois a mesma transformação é aplicada a todas as variáveis selecionadas sem a necessidade de escrever cada operação individualmente.

30

Para obter as estatísticas das variáveis quantitativas de acordo com o tipo de concreto, foi utilizada a combinação das funções group_by(), summarise() e across(). A função group_by() permitiu separar os registros conforme as classes de concreto, enquanto summarise() foi utilizada para resumir os dados. Por meio de across(), foram calculadas simultaneamente a média e o desvio padrão para todas as variáveis armazenadas no vetor variaveis_concreto.

A média foi utilizada para representar o valor central de cada variável, enquanto o desvio padrão permitiu avaliar a dispersão dos valores dentro de cada tipo de concreto. Os valores ausentes (NA) foram desconsiderados por meio do argumento na.rm = TRUE.

A utilização de across() apresenta maior facilidade de manutenção em comparação com vários comandos separados. Em uma abordagem individual, seria necessário escrever uma expressão para cada variável e para cada estatística. Com across(), as mesmas operações são aplicadas automaticamente a todas as variáveis selecionadas. Assim, caso novas variáveis quantitativas sejam adicionadas ao vetor variaveis_concreto, elas serão incluídas nos cálculos sem a necessidade de modificar o comando principal.

O resultado é apresentado de forma organizada, com uma linha para cada tipo de concreto e colunas correspondentes à média e ao desvio padrão de cada variável quantitativa.

# A tibble: 4 × 1
  obra   
  <chr>  
1 Bloco A
2 Bloco B
3 Bloco C
4 Bloco D
# A tibble: 4 × 1
  obra   
  <chr>  
1 BLOCO A
2 BLOCO B
3 BLOCO C
4 BLOCO D

Para verificar e padronizar a variável obra, foram utilizadas funções do pacote stringr. Inicialmente, foi realizada a identificação das categorias existentes por meio de distinct(), permitindo observar possíveis diferenças de grafia, utilização de letras maiúsculas e minúsculas e espaços desnecessários.

Para a padronização, foi utilizada a função str_trim(), responsável por remover espaços no início e no final dos textos. Em seguida, str_squish() foi utilizada para eliminar espaços duplicados, enquanto str_to_upper() padronizou todos os valores para letras maiúsculas.

Também foi utilizada str_replace_all() para corrigir possíveis diferenças de grafia entre categorias que representam a mesma obra. Dessa forma, os valores passaram a apresentar um padrão único, facilitando agrupamentos, filtros e análises posteriores.

A comparação entre os resultados antes e depois da padronização permite verificar as alterações realizadas na variável obra. Após o tratamento, categorias que apresentavam apenas diferenças de formatação ou grafia passam a ser representadas de maneira consistente, reduzindo o risco de uma mesma obra ser considerada como categorias diferentes durante as análises.

# A tibble: 32 × 4
   id_corpo_prova obra    tipo_concreto resistencia_mpa
   <chr>          <chr>   <chr>                   <dbl>
 1 CP-002         BLOCO A C30                      28.4
 2 CP-003         BLOCO C C30                      36.1
 3 CP-008         BLOCO D C30                      38.7
 4 CP-009         BLOCO B C30                      30.3
 5 CP-011         BLOCO C C30                      31.8
 6 CP-018         BLOCO B C30                      34.7
 7 CP-019         BLOCO B C30                      30.4
 8 CP-021         BLOCO A C30                      28.8
 9 CP-023         BLOCO C C30                      35.5
10 CP-027         BLOCO B C30                      39.4
# ℹ 22 more rows

Para localizar registros que contenham determinado padrão textual, foi utilizada a função str_detect() do pacote stringr. A condição de busca escolhida foi a identificação dos registros da classe C30 na variável tipo_concreto. Foi utilizada a função regex() com ignore_case = TRUE, permitindo localizar tanto C30 quanto possíveis variações de letras maiúsculas e minúsculas, como c30.

A utilização de padrões de texto é importante para o diagnóstico de bases de dados porque permite identificar rapidamente inconsistências de preenchimento, diferenças de formatação, categorias duplicadas e possíveis erros de digitação. Esse tipo de verificação é especialmente útil antes da realização de agrupamentos e análises estatísticas, pois valores aparentemente iguais podem ser tratados como categorias diferentes quando apresentam grafias distintas.

No caso desta base, a busca pelo padrão C30 permite verificar se existem registros dessa classe e se há alguma variação na forma como ela foi registrada. Dessa maneira, o uso de str_detect() contribui para a identificação de problemas de padronização e para o aumento da qualidade e confiabilidade dos dados.

Para comparar a distribuição da resistência à compressão entre os diferentes tipos de concreto, foi utilizado um gráfico de caixas, construído com a função geom_boxplot() do pacote ggplot2. Essa representação permite visualizar, para cada classe de concreto, a mediana, a dispersão dos resultados, os quartis e possíveis valores discrepantes.

A comparação entre as caixas permite verificar se as classes de concreto apresentam diferenças em relação aos valores centrais de resistência e à variabilidade dos resultados. Espera-se que as classes de maior resistência nominal, como C35 e C40, apresentem valores de resistência superiores aos observados nas classes C25 e C30. Além disso, caixas mais altas ou com maior amplitude indicam maior dispersão dos resultados, enquanto caixas mais concentradas indicam maior uniformidade entre os corpos de prova.

Dessa forma, o gráfico permite avaliar visualmente tanto o desempenho das diferentes classes de concreto quanto a variabilidade dos resultados obtidos no controle tecnológico.

O gráfico de dispersão foi utilizado para investigar visualmente a relação entre o consumo de cimento e a resistência à compressão do concreto. Cada ponto representa uma observação da base de dados, enquanto a linha de tendência foi adicionada por meio de geom_smooth() com um modelo de regressão linear.

A análise visual do gráfico permite verificar se existe uma tendência de aumento da resistência à compressão à medida que o consumo de cimento aumenta. Caso os pontos apresentem uma concentração crescente ao longo da linha de tendência, há uma evidência visual de associação positiva entre as duas variáveis.

Entretanto, o gráfico, por si só, não permite afirmar que o maior consumo de cimento seja a causa do aumento da resistência. A resistência do concreto também pode ser influenciada por outros fatores, como a relação água/cimento, tipo de cimento, idade do corpo de prova e características dos agregados.

Assim, o gráfico pode fornecer evidência visual compatível com a afirmação “quanto maior o consumo de cimento, maior tende a ser a resistência do concreto” caso seja observada uma tendência positiva, mas essa conclusão deve ser complementada por uma análise estatística da correlação ou do modelo de regressão.

O gráfico de dispersão foi utilizado para investigar a relação entre a relação água/cimento e a resistência à compressão dos corpos de prova. A linha de tendência foi adicionada para facilitar a identificação do comportamento geral dos dados.

A análise do gráfico permite investigar se existe uma tendência de redução da resistência à compressão à medida que a relação água/cimento aumenta. Esse comportamento é esperado tecnicamente, pois uma maior quantidade de água em relação ao cimento pode resultar em uma estrutura mais porosa após a hidratação, contribuindo para a redução da resistência.

Nos dados analisados, caso os pontos apresentem uma tendência descendente, haverá uma evidência visual de associação negativa entre a relação água/cimento e a resistência à compressão. Entretanto, a dispersão dos pontos também deve ser observada, pois indica que outros fatores podem influenciar a resistência.

Portanto, a relação observada merece investigação, principalmente para verificar a intensidade dessa associação e identificar possíveis observações que se afastem do comportamento geral. Uma análise de correlação ou um modelo de regressão poderia complementar a interpretação visual apresentada pelo gráfico.

# A tibble: 4 × 5
  obra    n_observacoes media mediana desvio_padrao
  <chr>           <int> <dbl>   <dbl>         <dbl>
1 BLOCO B            28  35.7    36.2          5.28
2 BLOCO A            28  33.2    30.5          6.42
3 BLOCO D            15  32.4    31.8          7.92
4 BLOCO C            28  32.4    31.6          6.79

A comparação foi realizada de forma descritiva, utilizando a média, a mediana e o desvio padrão da resistência à compressão para cada obra. Também foi elaborado um gráfico de caixas para permitir uma comparação visual da distribuição dos resultados.

Com base nos dados, o Bloco C não apresenta a maior resistência média. A resistência média observada foi de aproximadamente 32,37 MPa, enquanto os Blocos A, B e D apresentaram médias de aproximadamente 33,19 MPa, 35,90 MPa e 32,39 MPa, respectivamente.

Portanto, os dados não dão suporte, em termos descritivos, à afirmação de que os concretos utilizados no Bloco C apresentam desempenho superior aos demais blocos. O Bloco B apresentou a maior resistência média, enquanto o Bloco C apresentou uma média ligeiramente inferior à dos Blocos A e D.

A análise também mostra que a resistência apresenta variabilidade dentro de cada obra. Assim, embora a comparação das médias seja útil para uma primeira avaliação, outros fatores, como a classe do concreto, a relação água/cimento e a idade dos corpos de prova, também devem ser considerados antes de atribuir diferenças de desempenho exclusivamente à obra.

# A tibble: 4 × 3
  idade_dias n_observacoes resistencia_media
       <dbl>         <int>             <dbl>
1          7            16              28.8
2         14            15              34.7
3         28            57              34.7
4         56            11              33.1

A resistência média à compressão foi comparada entre as diferentes idades dos corpos de prova. Para isso, foram utilizadas as funções group_by() e summarise(), permitindo calcular a média da resistência para cada idade. Em seguida, foi utilizado um gráfico com pontos e linhas para facilitar a visualização do comportamento dos resultados.

Na base analisada, a resistência média foi de aproximadamente 28,78 MPa aos 7 dias, aumentando para 34,74 MPa aos 14 dias. Aos 28 dias, a média foi de aproximadamente 34,67 MPa, mantendo-se praticamente no mesmo nível observado aos 14 dias. Aos 56 dias, foi observada uma média de aproximadamente 33,12 MPa.

Assim, os dados indicam um aumento da resistência entre 7 e 14 dias, seguido de relativa estabilidade entre 14 e 28 dias e uma pequena redução da média aos 56 dias. Portanto, embora exista uma tendência geral de aumento da resistência com o avanço da idade nas primeiras idades, os dados não apresentam crescimento contínuo em todas as idades.

Essa variação merece investigação, pois a resistência do concreto normalmente tende a aumentar com a idade, especialmente nas primeiras idades. A presença de diferenças entre os resultados pode estar relacionada à variabilidade dos corpos de prova e a outros fatores, como classe do concreto, relação água/cimento e condições de produção e cura.

# A tibble: 4 × 7
  tipo_concreto n_observacoes resistencia_media resistencia_mediana
  <chr>                 <int>             <dbl>               <dbl>
1 C40                      16              43.3                43.2
2 C35                      22              37.1                36.8
3 C30                      32              32.1                31.8
4 C25                      29              27.1                27.8
# ℹ 3 more variables: desvio_padrao <dbl>, resistencia_minima <dbl>,
#   resistencia_maxima <dbl>

Para o acompanhamento da qualidade do concreto, foi construída uma tabela-resumo por tipo de concreto contendo seis informações estatísticas consideradas relevantes: número de observações, resistência média, mediana, desvio padrão, resistência mínima e resistência máxima.

A quantidade de observações foi incluída para verificar o volume de dados disponível para cada classe de concreto. A resistência média permite avaliar o desempenho médio dos corpos de prova e comparar as diferentes classes. A mediana complementa a média e permite identificar o comportamento central dos dados com menor influência de valores extremos.

O desvio padrão foi utilizado para avaliar a variabilidade dos resultados. Valores mais elevados indicam maior dispersão das resistências, podendo sinalizar menor uniformidade no controle tecnológico. As resistências mínima e máxima permitem identificar a amplitude dos resultados e possíveis valores que mereçam uma investigação mais detalhada.

A utilização do group_by() em conjunto com summarise() permite que todas essas informações sejam calculadas simultaneamente para cada tipo de concreto. Dessa forma, a tabela fornece ao engenheiro uma visão geral e organizada do desempenho e da variabilidade das diferentes classes, auxiliando no acompanhamento da qualidade do concreto.

5.8 Desafio Final

Código
# ============================================================
# DESAFIO FINAL — O ENGENHEIRO RESPONSÁVEL PELOS DADOS
# Controle tecnológico do concreto
# ============================================================

# ============================================================
# ETAPA 1 — CARREGAMENTO DOS PACOTES E DA BASE
# ============================================================

library(tidyverse)

# Importação da base de dados
dados <- read_csv2(
  "base_processamento_dados_engenharia_civil.csv",
  locale = locale(decimal_mark = "."),
  show_col_types = FALSE
)

# Inspeção inicial da estrutura da base
glimpse(dados)
Rows: 100
Columns: 10
$ id_corpo_prova        <chr> "CP-001", "CP-002", "CP-003", "CP-004", "CP-005"…
$ obra                  <chr> "Bloco A", "Bloco A", "Bloco C", "Bloco A", "Blo…
$ tipo_concreto         <chr> "C35", "C30", "C30", "C40", "C25", "C40", "C25",…
$ idade_dias            <dbl> 28, 7, 56, 28, 28, 28, 56, 28, 14, 7, 7, 28, 28,…
$ resistencia_mpa       <chr> "36.3", "28.4", "36.1", "47.2", "27.9", "41.5", …
$ cimento_kg_m3         <chr> "395", "340", "338", "407", "316", "398", "351",…
$ relacao_a_c           <chr> "0.5", "0.54", "0.56", "0.47", "0.61", "0.43", "…
$ abatimento_mm         <dbl> 1110, 1140, 1060, 1420, 1330, 980, 990, 1160, 12…
$ densidade_kg_m3       <dbl> 23320, 23890, 24270, 23450, 24480, 23240, 23850,…
$ absorção_agregado_pct <chr> "2.3", "1.85", "1.89", "1.97", "2.31", "0.8", "1…
Código
# Visualização das primeiras observações
dados |>
  slice_head(n = 10)
# A tibble: 10 × 10
   id_corpo_prova obra    tipo_concreto idade_dias resistencia_mpa cimento_kg_m3
   <chr>          <chr>   <chr>              <dbl> <chr>           <chr>        
 1 CP-001         Bloco A C35                   28 36.3            395          
 2 CP-002         Bloco A C30                    7 28.4            340          
 3 CP-003         Bloco C C30                   56 36.1            338          
 4 CP-004         Bloco A C40                   28 47.2            407          
 5 CP-005         Bloco B C25                   28 27.9            316          
 6 CP-006         Bloco B C40                   28 41.5            398          
 7 CP-007         Bloco C C25                   56 23.7            351          
 8 CP-008         Bloco D C30                   28 38,7            347          
 9 CP-009         Bloco B C30                   14 30.3            346          
10 CP-010         Bloco A C25                    7 25.3            315          
# ℹ 4 more variables: relacao_a_c <chr>, abatimento_mm <dbl>,
#   densidade_kg_m3 <dbl>, absorção_agregado_pct <chr>
Código
# ============================================================
# ETAPA 2 — INSPEÇÃO E IDENTIFICAÇÃO DE POSSÍVEIS PROBLEMAS
# ============================================================

# Verificação das categorias existentes em tipo_concreto
dados |>
  count(tipo_concreto, sort = TRUE)
# A tibble: 5 × 2
  tipo_concreto     n
  <chr>         <int>
1 C30              31
2 C25              29
3 C35              23
4 C40              16
5 c30               1
Código
# Verificação das categorias existentes em obra
dados |>
  count(obra, sort = TRUE)
# A tibble: 4 × 2
  obra        n
  <chr>   <int>
1 Bloco B    29
2 Bloco A    28
3 Bloco C    28
4 Bloco D    15
Código
# Verificação de possíveis diferenças de preenchimento em obra
dados |>
  distinct(obra) |>
  arrange(obra)
# A tibble: 4 × 1
  obra   
  <chr>  
1 Bloco A
2 Bloco B
3 Bloco C
4 Bloco D
Código
# Identificação de valores ausentes em cada variável
dados |>
  summarise(
    across(
      everything(),
      ~ sum(is.na(.x))
    )
  )
# A tibble: 1 × 10
  id_corpo_prova  obra tipo_concreto idade_dias resistencia_mpa cimento_kg_m3
           <int> <int>         <int>      <int>           <int>         <int>
1              0     0             0          0               1             0
# ℹ 4 more variables: relacao_a_c <int>, abatimento_mm <int>,
#   densidade_kg_m3 <int>, absorção_agregado_pct <int>
Código
# Localização dos registros que apresentam algum valor ausente
dados |>
  filter(
    if_any(
      everything(),
      is.na
    )
  )
# A tibble: 5 × 10
  id_corpo_prova obra    tipo_concreto idade_dias resistencia_mpa cimento_kg_m3
  <chr>          <chr>   <chr>              <dbl> <chr>           <chr>        
1 CP-015         Bloco B C35                   14 36.3            363          
2 CP-038         Bloco C C25                   28 25.7            309          
3 CP-077         Bloco D C25                   14 19.0            307          
4 CP-092         Bloco B C35                   14 <NA>            370          
5 CP-097         Bloco A C25                   28 26.7            356          
# ℹ 4 more variables: relacao_a_c <chr>, abatimento_mm <dbl>,
#   densidade_kg_m3 <dbl>, absorção_agregado_pct <chr>
Código
# ============================================================
# ETAPA 3 — LIMPEZA E PADRONIZAÇÃO DOS DADOS
# ============================================================

dados_limpos <- dados |>
  mutate(
    # Padronização dos textos da variável obra
    obra = str_trim(obra),
    obra = str_squish(obra),

    # Padronização da classe do concreto
    tipo_concreto = str_trim(tipo_concreto),
    tipo_concreto = str_to_upper(tipo_concreto),
    tipo_concreto = str_replace_all(tipo_concreto, "-", "")
  ) |>
  mutate(
    # Conversão das variáveis quantitativas para formato numérico.
    # A substituição de "O" por "0" corrige possíveis erros de digitação.
    across(
      -(1:3),
      ~ as.character(.x) |>
        str_replace_all("O", "0") |>
        str_replace_all(",", ".") |>
        parse_double()
    )
  )


# ============================================================
# ETAPA 4 — CORREÇÃO DE VALORES INCONSISTENTES
# ============================================================

# Algumas observações apresentam valores incompatíveis com
# as unidades esperadas. As correções abaixo procuram recuperar
# a escala provável dos dados sem alterar os valores que já
# estavam dentro de uma faixa coerente.

dados_limpos <- dados_limpos |>
  mutate(
    # Valores de abatimento acima de 300 mm são interpretados
    # como erro de escala.
    abatimento_mm = if_else(
      abatimento_mm > 300,
      abatimento_mm / 10,
      abatimento_mm
    ),

    # Valores de densidade abaixo de 1000 kg/m³ são interpretados
    # como erro de escala.
    densidade_kg_m3 = if_else(
      densidade_kg_m3 < 1000,
      densidade_kg_m3 * 10,
      densidade_kg_m3
    ),

    # Valores de consumo de cimento acima de 1000 kg/m³
    # são interpretados como erro de escala.
    cimento_kg_m3 = if_else(
      cimento_kg_m3 > 1000,
      cimento_kg_m3 / 10,
      cimento_kg_m3
    ),

    # Valores de absorção acima de 10% são tratados como
    # possível erro de escala.
    absorção_agregado_pct = if_else(
      absorção_agregado_pct > 10,
      absorção_agregado_pct / 10,
      absorção_agregado_pct
    ),

    # Idades muito elevadas são verificadas como possível
    # erro de digitação/escala.
    idade_dias = if_else(
      idade_dias > 200,
      idade_dias / 10,
      idade_dias
    )
  )


# ============================================================
# ETAPA 5 — VERIFICAÇÃO DA BASE APÓS A LIMPEZA
# ============================================================

glimpse(dados_limpos)
Rows: 100
Columns: 10
$ id_corpo_prova        <chr> "CP-001", "CP-002", "CP-003", "CP-004", "CP-005"…
$ obra                  <chr> "Bloco A", "Bloco A", "Bloco C", "Bloco A", "Blo…
$ tipo_concreto         <chr> "C35", "C30", "C30", "C40", "C25", "C40", "C25",…
$ idade_dias            <dbl> 28, 7, 56, 28, 28, 28, 56, 28, 14, 7, 7, 28, 28,…
$ resistencia_mpa       <dbl> 36.3, 28.4, 36.1, 47.2, 27.9, 41.5, 23.7, 38.7, …
$ cimento_kg_m3         <dbl> 395, 340, 338, 407, 316, 398, 351, 347, 346, 315…
$ relacao_a_c           <dbl> 0.50, 0.54, 0.56, 0.47, 0.61, 0.43, 0.65, 0.54, …
$ abatimento_mm         <dbl> 111, 114, 106, 142, 133, 98, 99, 116, 125, 127, …
$ densidade_kg_m3       <dbl> 23320, 23890, 24270, 23450, 24480, 23240, 23850,…
$ absorção_agregado_pct <dbl> 2.30, 1.85, 1.89, 1.97, 2.31, 0.80, 1.18, 1.33, …
Código
# Verificação das classes de concreto após a padronização
dados_limpos |>
  count(tipo_concreto, sort = TRUE)
# A tibble: 4 × 2
  tipo_concreto     n
  <chr>         <int>
1 C30              32
2 C25              29
3 C35              23
4 C40              16
Código
# Verificação dos valores ausentes após o tratamento
dados_limpos |>
  summarise(
    across(
      everything(),
      ~ sum(is.na(.x))
    )
  )
# A tibble: 1 × 10
  id_corpo_prova  obra tipo_concreto idade_dias resistencia_mpa cimento_kg_m3
           <int> <int>         <int>      <int>           <int>         <int>
1              0     0             0          0               1             0
# ℹ 4 more variables: relacao_a_c <int>, abatimento_mm <int>,
#   densidade_kg_m3 <int>, absorção_agregado_pct <int>
Código
# ============================================================
# ETAPA 6 — ESTATÍSTICAS DESCRITIVAS GERAIS
# ============================================================

resumo_geral <- dados_limpos |>
  summarise(
    n_observacoes = sum(!is.na(resistencia_mpa)),
    resistencia_media = mean(resistencia_mpa, na.rm = TRUE),
    resistencia_mediana = median(resistencia_mpa, na.rm = TRUE),
    desvio_padrao = sd(resistencia_mpa, na.rm = TRUE),
    resistencia_minima = min(resistencia_mpa, na.rm = TRUE),
    resistencia_maxima = max(resistencia_mpa, na.rm = TRUE)
  )

resumo_geral
# A tibble: 1 × 6
  n_observacoes resistencia_media resistencia_mediana desvio_padrao
          <int>             <dbl>               <dbl>         <dbl>
1            99              33.5                32.3          6.53
# ℹ 2 more variables: resistencia_minima <dbl>, resistencia_maxima <dbl>
Código
# ============================================================
# ETAPA 7 — ESTATÍSTICAS POR TIPO DE CONCRETO
# ============================================================

resumo_classes <- dados_limpos |>
  group_by(tipo_concreto) |>
  summarise(
    n_observacoes = sum(!is.na(resistencia_mpa)),
    resistencia_media = mean(resistencia_mpa, na.rm = TRUE),
    resistencia_mediana = median(resistencia_mpa, na.rm = TRUE),
    desvio_padrao = sd(resistencia_mpa, na.rm = TRUE),
    resistencia_minima = min(resistencia_mpa, na.rm = TRUE),
    resistencia_maxima = max(resistencia_mpa, na.rm = TRUE),
    .groups = "drop"
  ) |>
  arrange(desc(resistencia_media))

resumo_classes
# A tibble: 4 × 7
  tipo_concreto n_observacoes resistencia_media resistencia_mediana
  <chr>                 <int>             <dbl>               <dbl>
1 C40                      16              43.3                43.2
2 C35                      22              37.1                36.8
3 C30                      32              32.1                31.8
4 C25                      29              27.1                27.8
# ℹ 3 more variables: desvio_padrao <dbl>, resistencia_minima <dbl>,
#   resistencia_maxima <dbl>
Código
# ============================================================
# ETAPA 8 — PRIMEIRA VARIÁVEL DERIVADA
# RESISTÊNCIA DE REFERÊNCIA E RESISTÊNCIA RELATIVA
# ============================================================

# A resistência de referência foi definida de acordo com a
# classe nominal do concreto:
# C25 = 25 MPa
# C30 = 30 MPa
# C35 = 35 MPa
# C40 = 40 MPa

dados_limpos <- dados_limpos |>
  mutate(
    resistencia_referencia = case_when(
      tipo_concreto == "C25" ~ 25,
      tipo_concreto == "C30" ~ 30,
      tipo_concreto == "C35" ~ 35,
      tipo_concreto == "C40" ~ 40,
      TRUE ~ NA_real_
    ),

    # Razão entre a resistência observada e a resistência
    # de referência da respectiva classe.
    resistencia_relativa =
      resistencia_mpa / resistencia_referencia
  )


# ============================================================
# ETAPA 9 — SEGUNDA VARIÁVEL DERIVADA
# CLASSIFICAÇÃO DO RESULTADO
# ============================================================

dados_limpos <- dados_limpos |>
  mutate(
    classificacao = case_when(
      is.na(resistencia_mpa) ~ "Sem Dado",
      resistencia_mpa >= resistencia_referencia ~ "Conforme",
      resistencia_mpa >= 0.90 * resistencia_referencia ~ "Atenção",
      resistencia_mpa < 0.90 * resistencia_referencia ~ "Não Conforme"
    )
  )

# Quantidade de registros por classificação
dados_limpos |>
  count(classificacao, sort = TRUE)
# A tibble: 4 × 2
  classificacao     n
  <chr>         <int>
1 Conforme         75
2 Atenção          18
3 Não Conforme      6
4 Sem Dado          1
Código
# ============================================================
# ETAPA 10 — ANÁLISE DO COMPORTAMENTO POR OBRA
# ============================================================

comparacao_obras <- dados_limpos |>
  group_by(obra) |>
  summarise(
    n_observacoes = sum(!is.na(resistencia_mpa)),
    resistencia_media = mean(resistencia_mpa, na.rm = TRUE),
    resistencia_mediana = median(resistencia_mpa, na.rm = TRUE),
    desvio_padrao = sd(resistencia_mpa, na.rm = TRUE),
    .groups = "drop"
  ) |>
  arrange(desc(resistencia_media))

comparacao_obras
# A tibble: 4 × 5
  obra    n_observacoes resistencia_media resistencia_mediana desvio_padrao
  <chr>           <int>             <dbl>               <dbl>         <dbl>
1 Bloco B            28              35.7                36.2          5.28
2 Bloco A            28              33.2                30.5          6.42
3 Bloco D            15              32.4                31.8          7.92
4 Bloco C            28              32.4                31.6          6.79
Código
# ============================================================
# ETAPA 11 — ANÁLISE DA IDADE E RESISTÊNCIA
# ============================================================

resistencia_por_idade <- dados_limpos |>
  group_by(idade_dias) |>
  summarise(
    n_observacoes = sum(!is.na(resistencia_mpa)),
    resistencia_media = mean(resistencia_mpa, na.rm = TRUE),
    .groups = "drop"
  ) |>
  arrange(idade_dias)

resistencia_por_idade
# A tibble: 4 × 3
  idade_dias n_observacoes resistencia_media
       <dbl>         <int>             <dbl>
1          7            16              28.8
2         14            15              34.7
3         28            57              34.7
4         56            11              33.1
Código
# ============================================================
# ETAPA 12 — GRÁFICO 1
# DISTRIBUIÇÃO DA RESISTÊNCIA POR TIPO DE CONCRETO
# ============================================================

dados_limpos |>
  ggplot(
    aes(
      x = tipo_concreto,
      y = resistencia_mpa
    )
  ) +
  geom_boxplot(na.rm = TRUE) +
  labs(
    title = "Distribuição da resistência à compressão por tipo de concreto",
    x = "Tipo de concreto",
    y = "Resistência à compressão (MPa)"
  ) +
  theme_minimal()

Código
# ============================================================
# ETAPA 13 — GRÁFICO 2
# RELAÇÃO ENTRE CONSUMO DE CIMENTO E RESISTÊNCIA
# ============================================================

dados_limpos |>
  ggplot(
    aes(
      x = cimento_kg_m3,
      y = resistencia_mpa
    )
  ) +
  geom_point(na.rm = TRUE) +
  geom_smooth(
    method = "lm",
    se = TRUE,
    na.rm = TRUE
  ) +
  labs(
    title = "Relação entre consumo de cimento e resistência à compressão",
    x = "Consumo de cimento (kg/m³)",
    y = "Resistência à compressão (MPa)"
  ) +
  theme_minimal()

Código
# ============================================================
# ETAPA 14 — GRÁFICO 3
# RELAÇÃO ENTRE IDADE E RESISTÊNCIA MÉDIA
# ============================================================

resistencia_por_idade |>
  ggplot(
    aes(
      x = idade_dias,
      y = resistencia_media
    )
  ) +
  geom_point() +
  geom_line() +
  labs(
    title = "Resistência média à compressão em função da idade",
    x = "Idade do corpo de prova (dias)",
    y = "Resistência média à compressão (MPa)"
  ) +
  theme_minimal()

Código
# ============================================================
# ETAPA 15 — INFORMAÇÕES PARA AUXILIAR O ENGENHEIRO
# ============================================================

# Percentual de registros em cada classificação
informacoes_engenheiro <- dados_limpos |>
  count(classificacao) |>
  mutate(
    percentual = n / sum(n) * 100
  ) |>
  arrange(desc(n))

informacoes_engenheiro
# A tibble: 4 × 3
  classificacao     n percentual
  <chr>         <int>      <dbl>
1 Conforme         75         75
2 Atenção          18         18
3 Não Conforme      6          6
4 Sem Dado          1          1
Código
# Resistência média e quantidade de resultados por obra
dados_limpos |>
  group_by(obra) |>
  summarise(
    n_observacoes = sum(!is.na(resistencia_mpa)),
    resistencia_media = mean(resistencia_mpa, na.rm = TRUE),
    .groups = "drop"
  ) |>
  arrange(desc(resistencia_media))
# A tibble: 4 × 3
  obra    n_observacoes resistencia_media
  <chr>           <int>             <dbl>
1 Bloco B            28              35.7
2 Bloco A            28              33.2
3 Bloco D            15              32.4
4 Bloco C            28              32.4
Código
# Identificação dos registros classificados como "Não Conforme"
dados_limpos |>
  filter(classificacao == "Não Conforme") |>
  select(
    id_corpo_prova,
    obra,
    tipo_concreto,
    idade_dias,
    resistencia_mpa,
    resistencia_referencia,
    resistencia_relativa,
    classificacao
  )
# A tibble: 6 × 8
  id_corpo_prova obra    tipo_concreto idade_dias resistencia_mpa
  <chr>          <chr>   <chr>              <dbl>           <dbl>
1 CP-036         Bloco C C30                    7            24.5
2 CP-064         Bloco A C30                    7            25.6
3 CP-077         Bloco D C25                   14            19  
4 CP-086         Bloco C C35                    7            30.1
5 CP-094         Bloco A C35                    7            29.9
6 CP-096         Bloco D C25                    7            21.3
# ℹ 3 more variables: resistencia_referencia <dbl>, resistencia_relativa <dbl>,
#   classificacao <chr>
Código
# ============================================================
# ETAPA 16 — TABELA FINAL PARA O RELATÓRIO
# ============================================================

tabela_final <- dados_limpos |>
  select(
    id_corpo_prova,
    obra,
    tipo_concreto,
    idade_dias,
    resistencia_mpa,
    cimento_kg_m3,
    relacao_a_c,
    abatimento_mm,
    densidade_kg_m3,
    absorção_agregado_pct,
    resistencia_referencia,
    resistencia_relativa,
    classificacao
  )

tabela_final
# A tibble: 100 × 13
   id_corpo_prova obra    tipo_concreto idade_dias resistencia_mpa cimento_kg_m3
   <chr>          <chr>   <chr>              <dbl>           <dbl>         <dbl>
 1 CP-001         Bloco A C35                   28            36.3           395
 2 CP-002         Bloco A C30                    7            28.4           340
 3 CP-003         Bloco C C30                   56            36.1           338
 4 CP-004         Bloco A C40                   28            47.2           407
 5 CP-005         Bloco B C25                   28            27.9           316
 6 CP-006         Bloco B C40                   28            41.5           398
 7 CP-007         Bloco C C25                   56            23.7           351
 8 CP-008         Bloco D C30                   28            38.7           347
 9 CP-009         Bloco B C30                   14            30.3           346
10 CP-010         Bloco A C25                    7            25.3           315
# ℹ 90 more rows
# ℹ 7 more variables: relacao_a_c <dbl>, abatimento_mm <dbl>,
#   densidade_kg_m3 <dbl>, absorção_agregado_pct <dbl>,
#   resistencia_referencia <dbl>, resistencia_relativa <dbl>,
#   classificacao <chr>

Reflexão final

A principal diferença entre utilizar Base R e a família tidyverse está na forma de organizar e expressar as operações de processamento. O Base R oferece funções mais tradicionais e flexíveis, enquanto o tidyverse apresenta uma estrutura mais padronizada, na qual funções como filter(), select(), mutate(), summarise() e group_by() permitem construir uma sequência de transformação dos dados de maneira mais legível. Além disso, ferramentas como across(), stringr, tidyr e ggplot2 facilitam a aplicação das mesmas operações a várias variáveis, o tratamento de textos, a reorganização dos dados e a produção de gráficos.

O processamento e a limpeza dos dados são etapas fundamentais antes da aplicação de métodos estatísticos na Engenharia Civil porque resultados incorretos ou inconsistentes podem comprometer diretamente a interpretação do desempenho dos materiais. Erros de digitação, unidades incorretas, categorias duplicadas e valores ausentes precisam ser identificados antes da análise para evitar conclusões equivocadas e fornecer informações confiáveis para a tomada de decisões técnicas.

O principal problema identificado na base foi a presença de inconsistências de preenchimento e de escala, incluindo diferenças na forma de registrar categorias, valores numéricos incompatíveis com as unidades esperadas e registros ausentes. Como decisão de tratamento, os textos foram padronizados e os valores que apresentavam indícios claros de erro de escala foram corrigidos de acordo com a unidade esperada, enquanto os valores ausentes foram mantidos como NA, evitando a criação de valores artificiais.

Foram utilizadas principalmente funções da família tidyverse, como read_csv2(), glimpse(), count(), distinct(), filter(), select(), mutate(), summarise(), group_by(), across(), case_when(), if_else(), str_trim(), str_squish(), str_to_upper(), str_replace_all(), parse_double() e funções do ggplot2.

A solução é adequada porque organiza o processamento em etapas claramente identificadas, registra as decisões por meio de comentários e produz uma base limpa acompanhada de estatísticas, variáveis derivadas e representações gráficas. Dessa forma, outro profissional consegue compreender o procedimento realizado, reproduzir a análise e utilizar os resultados como apoio ao acompanhamento do controle tecnológico do concreto.

6 🧠 Considerações finais

A realização deste relatório permitiu compreender, de forma prática, a importância do tratamento e da organização dos dados antes da realização de análises estatísticas aplicadas à Engenharia Civil. A partir da base de dados do controle tecnológico do concreto, foi possível identificar diferentes tipos de inconsistências que poderiam comprometer a interpretação dos resultados caso os dados fossem utilizados diretamente em sua forma original.

Durante o processo de inspeção, foram identificados valores ausentes, erros de digitação, diferenças na padronização das categorias, problemas relacionados à representação dos números e valores com ordem de grandeza inadequada. A identificação desses problemas evidenciou que o tratamento dos dados é uma etapa essencial para garantir maior confiabilidade às análises realizadas.

A criação da base dados_limpos possibilitou organizar e padronizar as informações sem alterar a base original. Por meio das ferramentas da família tidyverse, foram realizadas correções, conversões e transformações que tornaram os dados mais adequados para a análise. Além disso, a utilização de estatísticas descritivas e gráficos permitiu explorar o comportamento da resistência à compressão e sua relação com outras variáveis relacionadas ao concreto.

Os resultados obtidos também demonstraram a importância de analisar os dados de maneira conjunta, considerando não apenas valores médios, mas também medidas como mediana, desvio padrão, valores mínimo e máximo e a distribuição dos resultados. As visualizações contribuíram para identificar diferenças entre os tipos de concreto e compreender melhor o comportamento das variáveis analisadas.

Dessa forma, os objetivos propostos para a atividade foram alcançados, uma vez que foi possível inspecionar, diagnosticar, limpar, transformar e explorar uma base de dados de uma situação prática da Engenharia Civil. O uso do R e das ferramentas do tidyverse mostrou-se adequado para estruturar um processo de análise organizado, eficiente e reprodutível.

Por fim, destaca-se que a qualidade das informações obtidas em uma análise está diretamente relacionada à qualidade dos dados utilizados. No contexto do controle tecnológico do concreto, a adoção de procedimentos padronizados para coleta, registro e armazenamento das informações pode reduzir a ocorrência de erros e contribuir para avaliações mais confiáveis. Assim, o conhecimento das ferramentas de tratamento e análise de dados constitui uma importante competência para o profissional de Engenharia Civil, especialmente no acompanhamento e na tomada de decisões relacionadas à qualidade dos materiais e dos processos construtivos.

7 📖 Referências

WICKHAM, H.; ÇETINKAYA-RUNDEL, M.; GROLEMUND, G. R para Ciência de Dados. 2. ed. [s.l.] O’Reilly Media, 2023.