Autor

Marco Antônio e Matheus Villela

Data de Publicação

30/08/2026, 12:37

1 📌 Introdução

No controle tecnológico do concreto, a qualidade das decisões técnicas depende diretamente da confiabilidade dos dados coletados em campo e em laboratório. Contudo, na prática profissional, é comum que bases de dados apresentem inconsistências, como valores ausentes, erros de digitação, padronização inadequada de categorias e registros incompatíveis com a realidade física do concreto. Esses problemas, quando não tratados adequadamente, podem comprometer as análises estatísticas e levar a interpretações equivocadas.

Esta atividade simula uma situação real em que o engenheiro recebe uma base de dados bruta contendo 100 registros e 10 variáveis relacionadas ao concreto. Utilizando a linguagem R, com ênfase nos recursos do Base R, o trabalho consiste em inspecionar, diagnosticar, limpar e explorar os dados, transformando informações inconsistentes em dados confiáveis para auxiliar na tomada de decisão no contexto da Engenharia Civil.

2 🎯 Objetivo geral

Inspecionar, diagnosticar, limpar e explorar uma base de dados do controle tecnológico do concreto utilizando o R (Base R), transformando dados brutos e inconsistentes em informações confiáveis para a tomada de decisão técnica no âmbito da Engenharia Civil.

2.1 Objetivos específicos

  • Conhecer a estrutura da base, identificando o número de observações, variáveis, tipos de dados e valores ausentes.

  • Diagnosticar problemas, como erros de digitação, separadores decimais incorretos, categorias despadronizadas e valores incompatíveis com o contexto da Engenharia Civil.

  • Padronizar e limpar os dados, corrigindo variáveis qualitativas e quantitativas, tratando valores ausentes e criando uma versão limpa da base.

  • Explorar os dados tratados por meio de estatísticas descritivas e análises agrupadas por obra, tipo de concreto e idade.

  • Criar variáveis derivadas com interpretação técnica, como resistência relativa, classificação de desempenho e indicador de desempenho acima da média.

  • Aplicar funções do Base R, como split(), lapply(), sapply(), apply(), aggregate(), for e if, para o processamento e a análise dos dados.

  • Responder questões práticas da Engenharia Civil, como a comparação de desempenho entre blocos e a relação entre diferentes variáveis do concreto.

  • Documentar e justificar as decisões de limpeza e análise, garantindo maior rastreabilidade e reprodutibilidade dos procedimentos realizados.

  • Desenvolver um script organizado e comentado que execute todo o fluxo de trabalho, desde a inspeção inicial até a geração de estatísticas e variáveis derivadas.

3 ⚙️ Metodologia

A metodologia adotada neste trabalho consiste no processamento completo de uma base de dados do controle tecnológico do concreto, utilizando a linguagem R, com ênfase nos recursos disponíveis no Base R.

O fluxo de trabalho segue uma sequência lógica composta pelas etapas de:

  1. Importação dos dados;
  2. Inspeção inicial da base;
  3. Diagnóstico de inconsistências;
  4. Limpeza e padronização dos dados;
  5. Tratamento dos valores ausentes;
  6. Exploração estatística;
  7. Criação de variáveis derivadas;
  8. Aplicação de funções de processamento;
  9. Interpretação dos resultados sob a perspectiva da Engenharia Civil.

As etapas foram organizadas em 35 questões, que orientam o desenvolvimento progressivo da atividade.

3.1 📋 Etapas de desenvolvimento

Questão 01 — Importação dos dados

Importe a base de dados para o R e atribua-a ao objeto dados, verificando a correta importação.

Questão 02 — Dimensões da base

Determine as dimensões da base, identificando o número de observações (linhas) e variáveis (colunas).

Questão 03 — Estrutura da base

Apresente a estrutura completa da base utilizando a função str() e analise detalhadamente o resultado obtido.

Questão 04 — Resumo estatístico

Gere um resumo estatístico das variáveis com a função summary() e identifique informações que merecem atenção.

Questão 05 — Classificação das variáveis

Classifique as variáveis em quantitativas e qualitativas, com base na estrutura apresentada pelo R.

Questão 06 — Valores ausentes

Verifique a existência de valores ausentes (missing values), identificando a quantidade, as variáveis e as observações afetadas.

Questão 07 — Valores incompatíveis

Verifique valores incompatíveis com o contexto da Engenharia Civil nas variáveis idade_dias, resistencia_mpa, abatimento_mm, densidade_kg_m3, relacao_a_c e absorção_agregado_pct, criando códigos para a localização das observações problemáticas.

Questão 08 — Erros de digitação

Localize possíveis erros de digitação e apresente os registros completos das observações afetadas.

Questão 09 — Padronização da variável obra

Verifique a padronização das categorias da variável obra e identifique possíveis inconsistências.

Questão 10 — Padronização da variável tipo_concreto

Verifique a padronização das categorias da variável tipo_concreto e identifique categorias que representam o mesmo tipo de concreto com grafias diferentes.

Questão 11 — Reavaliação dos tipos

Reavalie os tipos das variáveis após a identificação dos problemas e reflita sobre como um único valor digitado incorretamente pode alterar a interpretação de uma variável inteira pelo R.

Questão 12 — Cópia da base original

Crie uma cópia da base original chamada dados_limpos e discuta a importância de preservar a base original durante o processo de tratamento dos dados.

Questão 13 — Correção das variáveis qualitativas

Corrija os problemas encontrados nas variáveis qualitativas, padronizando suas categorias.

Questão 14 — Conversão das variáveis quantitativas

Converta para o tipo adequado as variáveis que deveriam ser quantitativas e verifique se a conversão foi realizada corretamente.

Questão 15 — Tratamento dos valores ausentes

Identifique os valores ausentes e discuta os procedimentos mais adequados para cada situação, considerando exclusão, substituição, manutenção do NA ou consulta à fonte original. Justifique tecnicamente as decisões adotadas.

Questão 16 — Reavaliação da base limpa

Reavalie a estrutura (str()) e o resumo (summary()) da base limpa e compare os resultados obtidos com aqueles observados na base original.

Questão 17 — Resistência média

Calcule a resistência média à compressão dos corpos de prova globalmente e por bloco da obra, tipo de concreto e idade do corpo de prova.

Questão 18 — Maior e menor resistência média

Identifique o bloco da obra que apresenta a maior e a menor resistência média, apresentando os códigos utilizados para essa identificação.

Questão 19 — Resistência por classe de concreto

Calcule a resistência média para cada classe de concreto (C25, C30, C35 e C40) e identifique a classe que apresenta a maior resistência média.

Questão 20 — Aplicação da função aggregate()

Utilize a função aggregate() para obter a média das variáveis resistencia_mpa, cimento_kg_m3, relacao_a_c, abatimento_mm e densidade_kg_m3 para cada tipo de concreto e interprete os resultados.

Questão 21 — Resistência relativa

Crie a variável resistencia_relativa, representando a razão entre a resistência observada e uma resistência de referência associada à classe do concreto, e explique como a referência foi definida.

Questão 22 — Classificação do desempenho

Crie a variável classificacao, classificando os corpos de prova segundo um critério relacionado à resistência, definindo e justificando tecnicamente os critérios utilizados.

Questão 23 — Desempenho acima da média

Crie a variável acima_media, indicando se a resistência do corpo de prova está acima ou abaixo da resistência média de seu respectivo tipo de concreto, utilizando os valores TRUE ou FALSE.

Questão 24 — Aplicação da função split()

Utilize a função split() para dividir a base de dados de acordo com a variável tipo_concreto e conte o número de observações em cada grupo.

Questão 25 — Aplicação da função lapply()

Utilizando a estrutura criada com split(), calcule a resistência média de cada tipo de concreto utilizando a função lapply().

Questão 26 — Aplicação da função sapply()

Repita a operação utilizando sapply() e explique a diferença entre os resultados produzidos por lapply() e sapply().

Questão 27 — Aplicação da função apply() para médias

Selecione as variáveis quantitativas relacionadas às propriedades do concreto e utilize a função apply() para calcular a média de cada variável.

Questão 28 — Aplicação da função apply() por observação

Utilize a função apply() para obter, para cada observação, uma medida resumo envolvendo as variáveis quantitativas selecionadas e discuta a interpretação física dessa medida.

Questão 29 — Aplicação de for e if

Utilizando for e ifsem utilizar ifelse() — percorra as 100 observações e identifique os corpos de prova cuja resistência está acima da resistência média de sua respectiva classe de concreto.

Questão 30 — Abordagem vetorizada

Repita a questão anterior utilizando uma abordagem vetorizada e compare as duas soluções quanto à simplicidade, legibilidade e eficiência, justificando sua análise.

Questão 31 — Comparação entre blocos

Verifique descritivamente a afirmação:

“Os concretos utilizados no Bloco C apresentam desempenho superior aos utilizados nos demais blocos.”

Realize a análise sem utilizar teste de hipótese.

Questão 32 — Consumo de cimento e resistência

Investigue a afirmação:

“Quanto maior o consumo de cimento, maior tende a ser a resistência do concreto.”

Identifique as variáveis que devem ser analisadas conjuntamente para avaliar essa relação.

Questão 33 — Relação água/cimento e resistência

Investigue a relação entre relacao_a_c e resistencia_mpa, analisando os padrões encontrados e interpretando os resultados considerando o comportamento esperado do concreto.

Questão 34 — Evolução da resistência com a idade

Compare a resistência média dos concretos em diferentes idades e analise a evolução da resistência com o aumento da idade dos corpos de prova.

Questão 35 — Informações estatísticas relevantes

Selecione e justifique as cinco informações estatísticas mais importantes para compor um relatório técnico destinado ao engenheiro responsável.

3.2 🏁 Etapa conclusiva — Script final

Como etapa conclusiva, desenvolva um script final em R, organizado e comentado, contemplando todo o fluxo de trabalho desenvolvido ao longo da atividade.

O script deverá contemplar:

  1. Inspeção inicial da base;
  2. Identificação de problemas e inconsistências;
  3. Verificação de valores ausentes;
  4. Verificação e correção de inconsistências nas variáveis;
  5. Produção de uma versão limpa dos dados;
  6. Geração de estatísticas descritivas relevantes;
  7. Criação de pelo menos duas variáveis derivadas;
  8. Produção de informações úteis para auxiliar o engenheiro responsável pela obra.

O código deverá ser estruturado de forma que outro engenheiro consiga compreender as etapas realizadas, permitindo a reprodução das análises e dos resultados obtidos.

Para isso, deverão ser utilizadas, sempre que pertinentes, as ferramentas de Base R trabalhadas em sala de aula, incluindo:

str(), summary(), subset(), apply(), lapply(), sapply(), ifelse(), for, if, tapply(), aggregate(), split(), with(), by(), within() e ave().

4 📚 Fundamentação teórica

A Estatística Descritiva reúne métodos utilizados para organizar, resumir e apresentar dados, facilitando sua interpretação e permitindo uma compreensão inicial do comportamento de um conjunto de informações. Entre seus principais recursos estão as medidas de posição, como a média, e as medidas de dispersão, utilizadas para avaliar a variabilidade dos dados (BATISTA, 2024).

O R é uma linguagem de programação e ambiente computacional amplamente utilizado para análise de dados e cálculos estatísticos. O Base R disponibiliza diversas funções para manipulação, processamento e análise de dados, incluindo summary(), mean(), apply(), lapply() e sapply() (BATISTA e ARTHUR, 2023).

Neste trabalho, esses conceitos são utilizados como fundamentação para o desenvolvimento das análises estatísticas e computacionais apresentadas nas etapas seguintes. A aplicação dessas ferramentas permite transformar uma base de dados inicialmente bruta em informações organizadas, interpretáveis e úteis para o processo de tomada de decisão na Engenharia Civil.

5 🔍 Resultados e Discussão

5.1 Questão 1 — Importação dos dados

A base de dados foi importada para o R utilizando a função read.csv() e armazenada no objeto dados.

Código
# Importação da base de dados
dados <- read.csv("base_de_dados.csv",
                  header = TRUE,
                  sep = ";")

# Visualização das primeiras observações
head(dados)
  id_corpo_prova    obra tipo_concreto idade_dias resistencia_mpa cimento_kg_m3
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
  relacao_a_c abatimento_mm densidade_kg_m3 absorção_agregado_pct
1         0.5           111            2332                  2.30
2        0.54           114            2389                  1.85
3        0.56           106            2427                  1.89
4        0.47           142            2345                  1.97
5        0.61           133            2448                  2.31
6        0.43            98            2324                  0.80

O código utilizado foi dividido em duas etapas. Primeiramente, read.csv() realiza a leitura do arquivo, enquanto header = TRUE informa que a primeira linha contém os nomes das variáveis. O argumento sep = ";" define o ponto e vírgula como separador das colunas, conforme a estrutura do arquivo.

Em seguida, head(dados) apresenta as primeiras observações da base, permitindo verificar se os dados foram importados e organizados corretamente.

5.2 Questão 2 — Dimensões da base

Para verificar o tamanho da base de dados, foi utilizada a função dim(), que retorna o número de linhas e colunas do objeto dados.

Código
# Verificação das dimensões da base
dim(dados)
[1] 100  10

A função dim() apresenta as dimensões no formato (linhas, colunas). Portanto, o primeiro valor corresponde ao número de observações, enquanto o segundo representa o número de variáveis.

No caso da base analisada, o resultado foi 100 observações e 10 variáveis, confirmando que a base possui 100 registros de corpos de prova, distribuídos em 10 características.

5.3 Questão 3 — Estrutura da base de dados

Para verificar a estrutura da base de dados, foi utilizada a função str(), que permite identificar o número de observações e variáveis, os nomes das colunas e os respectivos tipos de dados.

Código
str(dados)
'data.frame':   100 obs. of  10 variables:
 $ id_corpo_prova       : chr  "CP-001" "CP-002" "CP-003" "CP-004" ...
 $ obra                 : chr  "Bloco A" "Bloco A" "Bloco C" "Bloco A" ...
 $ tipo_concreto        : chr  "C35" "C30" "C30" "C40" ...
 $ idade_dias           : int  28 7 56 28 28 28 56 28 14 7 ...
 $ resistencia_mpa      : chr  "36.3" "28.4" "36.1" "47.2" ...
 $ cimento_kg_m3        : chr  "395" "340" "338" "407" ...
 $ relacao_a_c          : chr  "0.5" "0.54" "0.56" "0.47" ...
 $ abatimento_mm        : num  111 114 106 142 133 98 99 116 125 127 ...
 $ densidade_kg_m3      : num  2332 2389 2427 2345 2448 ...
 $ absorção_agregado_pct: num  2.3 1.85 1.89 1.97 2.31 0.8 1.18 1.33 2.92 1.94 ...

A análise da estrutura permite verificar como o R interpretou cada variável e identificar possíveis problemas de importação ou classificação. As variáveis quantitativas devem estar armazenadas como numéricas (“num” ou “int”), enquanto as variáveis qualitativas, como categorias de obra e tipo de concreto, podem ser armazenadas como caracteres (“chr”).

Essa verificação é importante antes da realização das análises estatísticas, pois a classificação incorreta de uma variável pode interferir nos cálculos e na interpretação dos resultados.

5.4 Questão 4 — Resumo estatístico da base de dados

Para obter uma visão geral das variáveis presentes na base de dados, foi utilizada a função summary(), que apresenta diferentes informações de acordo com o tipo de variável.

Código
summary(dados)
   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 : 84    N.unique : 68   N.unique : 25   1st Qu.:  99.5  
 N.blank  :  1    N.blank  :  0   N.blank  :  1   Median : 110.0  
 Min.nchar:  0    Min.nchar:  3   Min.nchar:  0   Mean   : 121.7  
 Max.nchar:  4    Max.nchar:  4   Max.nchar:  4   3rd Qu.: 122.5  
                                                  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            

Para as variáveis quantitativas, a função apresenta medidas como mínimo, quartis, mediana, média e máximo. Para as variáveis qualitativas, são apresentadas as categorias existentes e suas respectivas frequências. Também são disponibilizadas informações sobre valores em branco e características das variáveis de texto.

A tabela abaixo apresenta um resumo dos resultados obtidos por meio dessa função:

Informação apresentada Tipo de variável Significado
Length Qualitativa Quantidade total de elementos da variável.
N.unique Qualitativa Número de valores ou categorias diferentes.
Min. Quantitativa Menor valor observado.
1st Qu. Quantitativa Primeiro quartil (25% dos dados).
Median Quantitativa Mediana (50% dos dados).
Mean Quantitativa Média dos valores.
3rd Qu. Quantitativa Terceiro quartil (75% dos dados).
Max. Quantitativa Maior valor observado.
NA’s Quantitativa Quantidade de valores ausentes (missing values).
n. blank Qualitativa Quantidade de valores em branco.
mincharn Qualitativa Menor número de caracteres encontrados.
maxcharn Qualitativa Maior número de caracteres encontrados.

Dessa forma, o summary() fornece uma visão inicial da estrutura e das características dos dados, permitindo verificar a distribuição das variáveis, suas frequências e a presença de valores ausentes.

5.5 Questão 5 — Classificação das variáveis

Antes de verificar a classificação realizada pelo R, foram definidos os tipos esperados para cada variável, considerando sua natureza e seu significado no contexto do controle tecnológico do concreto. Assim, variáveis que representam categorias ou identificações são consideradas qualitativas, enquanto aquelas que representam medidas ou quantidades são consideradas quantitativas.

Para verificar como o R reconheceu cada variável, foi utilizada a função sapply() em conjunto com class().

Código
# Verificação do tipo de cada variável
sapply(dados, class)
       id_corpo_prova                  obra         tipo_concreto 
          "character"           "character"           "character" 
           idade_dias       resistencia_mpa         cimento_kg_m3 
            "integer"           "character"           "character" 
          relacao_a_c         abatimento_mm       densidade_kg_m3 
          "character"             "numeric"             "numeric" 
absorção_agregado_pct 
            "numeric" 

O resultado obtido foi:

Variável Tipo esperado Tipo reconhecido pelo R Classificação
id_corpo_prova Qualitativa character Qualitativa
obra Qualitativa character Qualitativa
tipo_concreto Qualitativa character Qualitativa
idade_dias Quantitativa integer Quantitativa
resistencia_mpa Quantitativa character Qualitativa
cimento_kg_m3 Quantitativa character Qualitativa
relacao_a_c Quantitativa character Qualitativa
abatimento_mm Quantitativa numeric Quantitativa
densidade_kg_m3 Quantitativa numeric Quantitativa
absorção_agregado_pct Quantitativa numeric Quantitativa

A partir da estrutura apresentada pelo R, as variáveis id_corpo_prova, obra e tipo_concreto foram reconhecidas como character, estando de acordo com o esperado para variáveis qualitativas. Já idade_dias, abatimento_mm, densidade_kg_m3 e absorção_agregado_pct foram reconhecidas como integer ou numeric, também de acordo com sua natureza quantitativa.

Entretanto, resistencia_mpa, cimento_kg_m3 e relacao_a_c são quantitativas por sua natureza, mas foram reconhecidas pelo R como character. Essa divergência pode estar relacionada a erros de digitação, caracteres inseridos nos valores ou separadores decimais inadequados, fazendo com que o R interprete essas informações como texto.

Portanto, a estrutura apresentada pelo R permite identificar que essas três variáveis precisarão ser corrigidas e convertidas para um formato quantitativo nas etapas posteriores de limpeza da base.

5.6 Questão 6 — Valores ausentes na base

Para verificar a existência de valores ausentes ou registros vazios na base, foram considerados tanto os valores NA quanto os principais padrões utilizados para representar dados não preenchidos: "", " ", "NA", "N/A", "-", "null" e "NULL".

Código
# Padrões considerados como valores ausentes
ausentes <- c("", " ", "NA", "N/A", "-", "null", "NULL")

# Quantidade total de valores ausentes ou vazios
sum(is.na(dados) | dados == "" | dados == " " |
      dados == "NA" | dados == "N/A" | dados == "-" |
      dados == "null" | dados == "NULL", na.rm = TRUE)
[1] 5
Código
# Quantidade por variável
sapply(dados, function(x)
  sum(is.na(x) | x %in% ausentes, na.rm = TRUE))
       id_corpo_prova                  obra         tipo_concreto 
                    0                     0                     0 
           idade_dias       resistencia_mpa         cimento_kg_m3 
                    0                     1                     0 
          relacao_a_c         abatimento_mm       densidade_kg_m3 
                    1                     1                     1 
absorção_agregado_pct 
                    1 
Código
# Observações que apresentam valores ausentes ou vazios
which(apply(dados, 1, function(x)
  any(is.na(x) | x %in% ausentes)))
[1] 15 38 77 92 97

O primeiro comando contabiliza o total de valores ausentes ou vazios encontrados na base. O segundo identifica em quais variáveis esses registros aparecem, enquanto o terceiro apresenta as observações afetadas.

Dessa forma, a análise não considera apenas os valores NA reconhecidos automaticamente pelo R, mas também registros preenchidos com diferentes formas de indicar ausência de informação.

5.6.1 Investigação dos erros de preenchimento e padronização

Nesta etapa, foram investigados possíveis erros de preenchimento e inconsistências de padronização em todas as células da base. A análise buscou identificar automaticamente diferenças de escrita, caracteres inadequados, espaços desnecessários e formas diferentes de representação dos mesmos valores.

Código
# Remoção de espaços desnecessários
sapply(dados, function(x) sum(grepl("^ | $", x)))
       id_corpo_prova                  obra         tipo_concreto 
                    0                     1                     0 
           idade_dias       resistencia_mpa         cimento_kg_m3 
                    0                     0                     0 
          relacao_a_c         abatimento_mm       densidade_kg_m3 
                    0                     0                     0 
absorção_agregado_pct 
                    0 
Código
# Identificação de categorias diferentes nas variáveis qualitativas
unique(dados$obra)
[1] "Bloco A"  "Bloco C"  "Bloco B"  "Bloco D"  "Bloco B "
Código
unique(dados$tipo_concreto)
[1] "C35" "C30" "C40" "C25" "c30"
Código
# Identificação de valores que possuem vírgula decimal
sapply(dados, function(x) sum(grepl(",", x)))
       id_corpo_prova                  obra         tipo_concreto 
                    0                     0                     0 
           idade_dias       resistencia_mpa         cimento_kg_m3 
                    0                     2                     0 
          relacao_a_c         abatimento_mm       densidade_kg_m3 
                    1                     0                     0 
absorção_agregado_pct 
                    0 
Código
# Identificação de valores contendo letras em variáveis quantitativas
variaveis_quantitativas <- c(
  "idade_dias",
  "resistencia_mpa",
  "cimento_kg_m3",
  "relacao_a_c",
  "abatimento_mm",
  "densidade_kg_m3",
  "absorção_agregado_pct"
)

sapply(dados[variaveis_quantitativas], function(x)
  sum(grepl("[A-Za-z]", x))
)
           idade_dias       resistencia_mpa         cimento_kg_m3 
                    0                     1                     1 
          relacao_a_c         abatimento_mm       densidade_kg_m3 
                    0                     0                     0 
absorção_agregado_pct 
                    0 

A investigação permitiu identificar erros de preenchimento e diferenças de padronização nas variáveis da base. Foram encontrados registros com espaços adicionais, diferenças de maiúsculas e minúsculas, utilização de vírgula como separador decimal e presença de caracteres alfabéticos em variáveis que deveriam conter valores numéricos.

Essas inconsistências podem fazer com que valores que representam a mesma informação sejam interpretados de maneiras diferentes pelo R.

5.7 Questão 7 — Valores potencialmente incompatíveis

Nesta etapa, foram investigados valores que podem ser incompatíveis ou suspeitos no contexto da Engenharia Civil. Os critérios utilizados foram baseados, quando aplicável, em referências normativas e, nos demais casos, na identificação de valores que se afastam significativamente do padrão observado na própria base.

Para o abatimento, foi considerada a ABNT NBR 16889:2020 (Associação Brasileira de Normas Técnicas, 2020), que estabelece o método para determinação da consistência do concreto pelo abatimento do tronco de cone, em conjunto com as classes de abatimento estabelecidas pela ABNT NBR 8953:2015 (Associação Brasileira de Normas Técnicas, 2015).

Para a resistência à compressão, foi considerada a ABNT NBR 5739:2018 (Associação Brasileira de Normas Técnicas, 2018), que estabelece o método para determinação da resistência à compressão de corpos de prova cilíndricos de concreto. Como a norma não estabelece um intervalo universal de resistência válido para todos os concretos, os valores utilizados na triagem foram definidos a partir do contexto e do padrão observado na própria base.

Para densidade e absorção, foi considerada a ABNT NBR 9778:2005 (Associação Brasileira de Normas Técnicas, 2005), que estabelece métodos para determinação da absorção de água, índice de vazios e massa específica de argamassas e concretos endurecidos.

Para idade dos corpos de prova e relação água/cimento, foi realizada uma análise exploratória baseada nos valores observados na própria base, pois esses parâmetros dependem das condições de projeto, dosagem e programa experimental.

Código
# Valores potencialmente incompatíveis com o contexto dos dados

# Idade dos corpos de prova
dados[dados$idade_dias <= 0 | dados$idade_dias > 56, ]
   id_corpo_prova    obra tipo_concreto idade_dias resistencia_mpa
85         CP-085 Bloco A           C30        280            38.3
   cimento_kg_m3 relacao_a_c abatimento_mm densidade_kg_m3
85           342         0.6           141            2377
   absorção_agregado_pct
85                  1.86
Código
# Resistência à compressão
dados[dados$resistencia_mpa < 20 | dados$resistencia_mpa > 60, ]
   id_corpo_prova    obra tipo_concreto idade_dias resistencia_mpa
77         CP-077 Bloco D           C25         14            19.0
92         CP-092 Bloco B           C35         14                
   cimento_kg_m3 relacao_a_c abatimento_mm densidade_kg_m3
77           307        0.63           119              NA
92           370        0.47           111            2380
   absorção_agregado_pct
77                  1.38
92                  2.38
Código
# Abatimento
dados[dados$abatimento_mm < 10 | dados$abatimento_mm > 220, ]
   id_corpo_prova    obra tipo_concreto idade_dias resistencia_mpa
NA           <NA>    <NA>          <NA>         NA            <NA>
32         CP-032 Bloco D           C35         14            36.6
   cimento_kg_m3 relacao_a_c abatimento_mm densidade_kg_m3
NA          <NA>        <NA>            NA              NA
32           370        0.53          1250            2383
   absorção_agregado_pct
NA                    NA
32                  2.13
Código
# Densidade
dados[dados$densidade_kg_m3 < 2000 | dados$densidade_kg_m3 > 2600, ]
   id_corpo_prova    obra tipo_concreto idade_dias resistencia_mpa
53         CP-053 Bloco D           C30         28            27.4
NA           <NA>    <NA>          <NA>         NA            <NA>
   cimento_kg_m3 relacao_a_c abatimento_mm densidade_kg_m3
53           349        0.61            97             238
NA          <NA>        <NA>            NA              NA
   absorção_agregado_pct
53                  1.79
NA                    NA
Código
# Relação água/cimento
dados[dados$relacao_a_c < 0.40 | dados$relacao_a_c > 0.70, ]
   id_corpo_prova    obra tipo_concreto idade_dias resistencia_mpa
38         CP-038 Bloco C           C25         28            25.7
45         CP-045 Bloco C           C40         14            42.9
   cimento_kg_m3 relacao_a_c abatimento_mm densidade_kg_m3
38           309                       146            2334
45           407        0,55            76            2381
   absorção_agregado_pct
38                  2.12
45                  2.12
Código
# Absorção
dados[dados$`absorção_agregado_pct` < 0 | 
        dados$`absorção_agregado_pct` > 10, ]
   id_corpo_prova    obra tipo_concreto idade_dias resistencia_mpa
72         CP-072 Bloco B           C40         14            37.3
NA           <NA>    <NA>          <NA>         NA            <NA>
   cimento_kg_m3 relacao_a_c abatimento_mm densidade_kg_m3
72           403        0.48            98            2414
NA          <NA>        <NA>            NA              NA
   absorção_agregado_pct
72                  18.4
NA                    NA

Os códigos acima realizam uma triagem inicial, permitindo localizar as observações que merecem investigação. Um valor identificado não deve ser automaticamente considerado incorreto, pois pode representar uma condição real de ensaio ou de dosagem.

Na base analisada, esses critérios permitem identificar, entre outros, idade de 280 dias, abatimento de 1250 mm, densidade de 238 kg/m³ e absorção de 18,4%. Esses valores apresentam grande afastamento em relação aos demais registros e, portanto, devem ser conferidos antes da utilização da base nas análises estatísticas.

5.8 Questão 8 — Possíveis erros de digitação

Nesta etapa, foram procurados valores que apresentam características de erro de digitação ou preenchimento, como uso incorreto de letras, separadores decimais, espaços desnecessários e categorias com grafia diferente das demais.

Para localizar esses problemas, foram utilizados códigos que verificam automaticamente padrões diferentes dos predominantes na base.

Código
# 1. Resistência com caracteres diferentes do padrão numérico
dados[!grepl("^[0-9]+([.,][0-9]+)?$", dados$resistencia_mpa), ]
   id_corpo_prova    obra tipo_concreto idade_dias resistencia_mpa
19         CP-019 Bloco B           C30         28            3O,4
92         CP-092 Bloco B           C35         14                
   cimento_kg_m3 relacao_a_c abatimento_mm densidade_kg_m3
19           356        0.59            83            2360
92           370        0.47           111            2380
   absorção_agregado_pct
19                  0.89
92                  2.38
Código
# 2. Relação água/cimento com separador decimal diferente
dados[!grepl("^[0-9]+([.,][0-9]+)?$", dados$relacao_a_c), ]
   id_corpo_prova    obra tipo_concreto idade_dias resistencia_mpa
38         CP-038 Bloco C           C25         28            25.7
   cimento_kg_m3 relacao_a_c abatimento_mm densidade_kg_m3
38           309                       146            2334
   absorção_agregado_pct
38                  2.12
Código
# 3. Consumo de cimento com caracteres não numéricos
dados[!grepl("^[0-9]+([.,][0-9]+)?$", dados$cimento_kg_m3), ]
   id_corpo_prova    obra tipo_concreto idade_dias resistencia_mpa
64         CP-064 Bloco A           C30          7            25.6
   cimento_kg_m3 relacao_a_c abatimento_mm densidade_kg_m3
64          390O        0.59           114            2427
   absorção_agregado_pct
64                  1.26
Código
# 4. Categorias de obra com espaços no início ou no final
dados[trimws(dados$obra) != dados$obra, ]
   id_corpo_prova     obra tipo_concreto idade_dias resistencia_mpa
27         CP-027 Bloco B            C30         28            39.4
   cimento_kg_m3 relacao_a_c abatimento_mm densidade_kg_m3
27           365        0.57           102            2413
   absorção_agregado_pct
27                   2.1
Código
# 5. Categorias de tipo de concreto diferentes do padrão
dados[!dados$tipo_concreto %in% c("C25", "C30", "C35", "C40"), ]
   id_corpo_prova    obra tipo_concreto idade_dias resistencia_mpa
59         CP-059 Bloco B           c30          7            29.9
   cimento_kg_m3 relacao_a_c abatimento_mm densidade_kg_m3
59           340        0.58            95            2388
   absorção_agregado_pct
59                   1.1

A aplicação dos códigos permite localizar os seguintes possíveis erros de preenchimento:

Observação Variável Valor encontrado Possível problema
CP-008 resistencia_mpa 38,7 Uso de vírgula como separador decimal
CP-019 resistencia_mpa 3O,4 Letra O utilizada no lugar do número 0
CP-027 obra Bloco B Espaço desnecessário ao final do texto
CP-045 relacao_a_c 0,55 Uso de vírgula como separador decimal
CP-059 tipo_concreto c30 Categoria escrita com letra minúscula
CP-064 cimento_kg_m3 390O Letra O utilizada no lugar do número 0

Além desses casos, os códigos permitem verificar a existência de outros registros com padrões diferentes sem que seja necessário conhecer previamente onde os problemas estão.

Os casos identificados representam problemas de preenchimento ou padronização, e não necessariamente erros nos valores físicos medidos. Por exemplo, 38,7 pode representar corretamente uma resistência de 38,7 MPa, mas está registrada utilizando vírgula decimal, enquanto os demais valores utilizam ponto.

O caso mais evidente de erro de digitação ocorre em CP-019, onde 3O,4 apresenta a letra O no lugar do número 0, e em CP-064, onde 390O apresenta o mesmo problema. Esses registros impedem que o R reconheça diretamente os valores como numéricos.

Os registros completos identificados são apresentados a seguir:

Código
# Apresentação dos registros completos com possíveis
# erros de digitação ou preenchimento

dados[c(8, 19, 27, 45, 59, 64), ]
   id_corpo_prova     obra tipo_concreto idade_dias resistencia_mpa
8          CP-008  Bloco D           C30         28            38,7
19         CP-019  Bloco B           C30         28            3O,4
27         CP-027 Bloco B            C30         28            39.4
45         CP-045  Bloco C           C40         14            42.9
59         CP-059  Bloco B           c30          7            29.9
64         CP-064  Bloco A           C30          7            25.6
   cimento_kg_m3 relacao_a_c abatimento_mm densidade_kg_m3
8            347        0.54           116            2387
19           356        0.59            83            2360
27           365        0.57           102            2413
45           407        0,55            76            2381
59           340        0.58            95            2388
64          390O        0.59           114            2427
   absorção_agregado_pct
8                   1.33
19                  0.89
27                  2.10
45                  2.12
59                  1.10
64                  1.26

Assim, foram identificados seis registros que apresentam possíveis problemas de digitação ou padronização, envolvendo as variáveis resistencia_mpa, obra, relacao_a_c, tipo_concreto e cimento_kg_m3.

5.9 Questão 9 — Padronização da variável obra

Para verificar se todas as categorias da variável obra estão padronizadas, foram analisados os valores existentes e também removidos temporariamente os espaços no início e no final dos textos para comparação.

Código
# Verificação das categorias existentes
unique(dados$obra)
[1] "Bloco A"  "Bloco C"  "Bloco B"  "Bloco D"  "Bloco B "
Código
# Identificação de categorias que possuem espaços extras
dados[trimws(dados$obra) != dados$obra, ]
   id_corpo_prova     obra tipo_concreto idade_dias resistencia_mpa
27         CP-027 Bloco B            C30         28            39.4
   cimento_kg_m3 relacao_a_c abatimento_mm densidade_kg_m3
27           365        0.57           102            2413
   absorção_agregado_pct
27                   2.1
Código
# Comparação das categorias após remoção dos espaços
unique(trimws(dados$obra))
[1] "Bloco A" "Bloco C" "Bloco B" "Bloco D"

A análise identificou uma inconsistência na variável obra. O registro CP-027 apresenta a categoria:

"Bloco B "

enquanto os demais registros correspondentes apresentam:

"Bloco B"

A diferença está apenas na presença de um espaço em branco ao final do texto. Embora visualmente pareçam iguais, o R considera "Bloco B " e "Bloco B" como categorias diferentes.

Portanto, a variável obra não está completamente padronizada.

5.10 Questão 10 — Padronização da variável tipo_concreto

Para verificar se as categorias da variável tipo_concreto estão padronizadas, foram observadas as categorias existentes e realizada uma comparação após a padronização temporária de letras maiúsculas e espaços.

Código
# Verificação das categorias existentes
unique(dados$tipo_concreto)
[1] "C35" "C30" "C40" "C25" "c30"
Código
# Padronização temporária para comparação
tipo_padronizado <- toupper(trimws(dados$tipo_concreto))

# Identificação das categorias diferentes do padrão
dados[tipo_padronizado != dados$tipo_concreto, ]
   id_corpo_prova    obra tipo_concreto idade_dias resistencia_mpa
59         CP-059 Bloco B           c30          7            29.9
   cimento_kg_m3 relacao_a_c abatimento_mm densidade_kg_m3
59           340        0.58            95            2388
   absorção_agregado_pct
59                   1.1
Código
# Verificação das categorias após a padronização
unique(tipo_padronizado)
[1] "C35" "C30" "C40" "C25"

A análise identificou uma inconsistência no registro CP-059, em que a variável tipo_concreto foi preenchida como:

"c30"

enquanto os demais registros utilizam:

"C30"

Nesse caso, "c30" e "C30" representam o mesmo tipo de concreto, porém foram escritos de maneiras diferentes devido ao uso de letra minúscula.

Portanto, a variável tipo_concreto não está totalmente padronizada.

5.11 Questão 11 — Reavaliação dos tipos

Após a identificação dos problemas, os tipos das variáveis foram novamente verificados utilizando sapply() e class().

Código
# Verificação dos tipos das variáveis
sapply(dados, class)
       id_corpo_prova                  obra         tipo_concreto 
          "character"           "character"           "character" 
           idade_dias       resistencia_mpa         cimento_kg_m3 
            "integer"           "character"           "character" 
          relacao_a_c         abatimento_mm       densidade_kg_m3 
          "character"             "numeric"             "numeric" 
absorção_agregado_pct 
            "numeric" 

O resultado obtido permanece:

Variável Tipo reconhecido pelo R
id_corpo_prova character
obra character
tipo_concreto character
idade_dias integer
resistencia_mpa character
cimento_kg_m3 character
relacao_a_c character
abatimento_mm numeric
densidade_kg_m3 numeric
absorção_agregado_pct numeric

O resultado permanece com resistencia_mpa, cimento_kg_m3 e relacao_a_c como character, embora sejam variáveis quantitativas por sua natureza.

Isso ocorre porque um único valor incompatível pode fazer com que o R interprete toda a coluna como texto. Por exemplo, os valores 3O,4 e 390O contêm a letra O no lugar do número 0, impedindo que o R reconheça essas colunas diretamente como numéricas.

5.12 Questão 12 — Cópia da base original

Foi criada uma cópia da base original para realizar as etapas de limpeza sem alterar os dados inicialmente importados.

Código
# Criação da cópia para limpeza
dados_limpos <- dados

É recomendável preservar a base original para evitar a perda dos dados brutos, permitir a comparação entre os dados originais e os dados tratados e possibilitar a reversão ou revisão das decisões de limpeza, garantindo maior rastreabilidade e segurança na análise.

5.13 Questão 13 — Correção das variáveis qualitativas

Foram corrigidas as inconsistências identificadas nas variáveis qualitativas obra e tipo_concreto, padronizando espaços e letras maiúsculas.

Código
# Padronização das variáveis qualitativas
dados_limpos$obra <- trimws(dados_limpos$obra)
dados_limpos$tipo_concreto <- toupper(trimws(dados_limpos$tipo_concreto))

# Verificação das categorias após a correção
unique(dados_limpos$obra)
[1] "Bloco A" "Bloco C" "Bloco B" "Bloco D"
Código
unique(dados_limpos$tipo_concreto)
[1] "C35" "C30" "C40" "C25"

A função trimws() remove espaços desnecessários no início e no final dos textos, enquanto toupper() transforma as letras em maiúsculas. Dessa forma, categorias como "Bloco B " e "c30" passam a ser representadas de forma padronizada como "Bloco B" e "C30".

5.14 Questão 14 - Correção das variáveis quantitativas

As variáveis quantitativas foram convertidas para o tipo numérico, corrigindo também os valores que apresentavam caracteres incompatíveis com esse formato.

Código
dados_limpos$idade_dias <- as.numeric(dados_limpos$idade_dias)

dados_limpos$resistencia_mpa <- as.numeric(
  gsub(",", ".",
       gsub("O", "0", dados_limpos$resistencia_mpa)
  )
)

dados_limpos$cimento_kg_m3 <- as.numeric(
  gsub("O", "0", dados_limpos$cimento_kg_m3)
)

dados_limpos$relacao_a_c <- as.numeric(
  gsub(",", ".", dados_limpos$relacao_a_c)
)

dados_limpos$abatimento_mm <- as.numeric(dados_limpos$abatimento_mm)
dados_limpos$densidade_kg_m3 <- as.numeric(dados_limpos$densidade_kg_m3)

dados_limpos$`absorção_agregado_pct` <- as.numeric(
  dados_limpos$`absorção_agregado_pct`
)

# Verificação
str(dados_limpos)
'data.frame':   100 obs. of  10 variables:
 $ id_corpo_prova       : chr  "CP-001" "CP-002" "CP-003" "CP-004" ...
 $ obra                 : chr  "Bloco A" "Bloco A" "Bloco C" "Bloco A" ...
 $ tipo_concreto        : chr  "C35" "C30" "C30" "C40" ...
 $ idade_dias           : num  28 7 56 28 28 28 56 28 14 7 ...
 $ resistencia_mpa      : num  36.3 28.4 36.1 47.2 27.9 41.5 23.7 38.7 30.3 25.3 ...
 $ cimento_kg_m3        : num  395 340 338 407 316 398 351 347 346 315 ...
 $ relacao_a_c          : num  0.5 0.54 0.56 0.47 0.61 0.43 0.65 0.54 0.54 0.6 ...
 $ abatimento_mm        : num  111 114 106 142 133 98 99 116 125 127 ...
 $ densidade_kg_m3      : num  2332 2389 2427 2345 2448 ...
 $ absorção_agregado_pct: num  2.3 1.85 1.89 1.97 2.31 0.8 1.18 1.33 2.92 1.94 ...

A função str() foi utilizada para confirmar que as variáveis passaram a ser reconhecidas pelo R como numéricas (num).

5.15 Questão 15 — Tratamento dos valores ausentes

Inicialmente, foram identificados os valores ausentes (NA) presentes na base e as respectivas variáveis afetadas.

Código
# Quantidade de valores ausentes por variável
sapply(dados_limpos, function(x) sum(is.na(x)))
       id_corpo_prova                  obra         tipo_concreto 
                    0                     0                     0 
           idade_dias       resistencia_mpa         cimento_kg_m3 
                    0                     1                     0 
          relacao_a_c         abatimento_mm       densidade_kg_m3 
                    1                     1                     1 
absorção_agregado_pct 
                    1 
Código
# Localização das observações que possuem valores ausentes
dados_limpos[!complete.cases(dados_limpos), ]
   id_corpo_prova    obra tipo_concreto idade_dias resistencia_mpa
15         CP-015 Bloco B           C35         14            36.3
38         CP-038 Bloco C           C25         28            25.7
77         CP-077 Bloco D           C25         14            19.0
92         CP-092 Bloco B           C35         14              NA
97         CP-097 Bloco A           C25         28            26.7
   cimento_kg_m3 relacao_a_c abatimento_mm densidade_kg_m3
15           363        0.49            NA            2359
38           309          NA           146            2334
77           307        0.63           119              NA
92           370        0.47           111            2380
97           356        0.64           122            2440
   absorção_agregado_pct
15                  1.93
38                  2.12
77                  1.38
92                  2.38
97                    NA

A função is.na() identifica os valores ausentes e, em conjunto com sum(), permite contabilizar a quantidade de NA em cada variável. Já complete.cases() permite identificar as observações que possuem todos os valores preenchidos.

Como não é possível consultar a fonte original para recuperar os valores ausentes, optou-se pela exclusão das observações que apresentam dados vazios. Essa decisão evita a introdução de valores estimados ou artificiais na base, preservando a confiabilidade dos resultados.

Para preservar a base dados_limpos e permitir a comparação entre as versões, foi criada uma nova variável denominada dados_sem_na:

Código
# Criação de uma nova base sem observações com valores ausentes
dados_sem_na <- dados_limpos[complete.cases(dados_limpos), ]

# Verificação da quantidade de observações após a exclusão
nrow(dados_sem_na)
[1] 95

A função complete.cases() seleciona apenas as observações que não possuem valores ausentes. Dessa forma, dados_sem_na contém somente os registros completos, enquanto dados_limpos é mantida como referência para comparação.

A exclusão das observações foi adotada de forma criteriosa, considerando o impacto da perda de registros sobre o tamanho da amostra. Essa abordagem é preferível à substituição dos valores por média, mediana ou outros valores estimados, pois evita a criação de informações que não foram efetivamente observadas.

5.16 Questão 16 — Reavaliação da base limpa

Após a correção das variáveis e a remoção das observações que apresentavam valores ausentes, foi realizada uma nova verificação da estrutura e do resumo estatístico da base dados_sem_na.

Código
# Verificação da estrutura da base sem valores ausentes
str(dados_sem_na)
'data.frame':   95 obs. of  10 variables:
 $ id_corpo_prova       : chr  "CP-001" "CP-002" "CP-003" "CP-004" ...
 $ obra                 : chr  "Bloco A" "Bloco A" "Bloco C" "Bloco A" ...
 $ tipo_concreto        : chr  "C35" "C30" "C30" "C40" ...
 $ idade_dias           : num  28 7 56 28 28 28 56 28 14 7 ...
 $ resistencia_mpa      : num  36.3 28.4 36.1 47.2 27.9 41.5 23.7 38.7 30.3 25.3 ...
 $ cimento_kg_m3        : num  395 340 338 407 316 398 351 347 346 315 ...
 $ relacao_a_c          : num  0.5 0.54 0.56 0.47 0.61 0.43 0.65 0.54 0.54 0.6 ...
 $ abatimento_mm        : num  111 114 106 142 133 98 99 116 125 127 ...
 $ densidade_kg_m3      : num  2332 2389 2427 2345 2448 ...
 $ absorção_agregado_pct: num  2.3 1.85 1.89 1.97 2.31 0.8 1.18 1.33 2.92 1.94 ...
Código
# Verificação do resumo estatístico
summary(dados_sem_na)
   id_corpo_prova        obra      tipo_concreto   idade_dias    
 Length   :95     Length   :95   Length   :95    Min.   :  7.00  
 N.unique :95     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   : 28.44  
 Max.nchar: 6     Max.nchar: 7   Max.nchar: 3    3rd Qu.: 28.00  
                                                 Max.   :280.00  
 resistencia_mpa cimento_kg_m3     relacao_a_c     abatimento_mm   
 Min.   :21.30   Min.   : 295.0   Min.   :0.4300   Min.   :  64.0  
 1st Qu.:29.30   1st Qu.: 340.0   1st Qu.:0.5100   1st Qu.:  99.0  
 Median :32.70   Median : 353.0   Median :0.5600   Median : 109.0  
 Mean   :33.83   Mean   : 395.4   Mean   :0.5536   Mean   : 121.6  
 3rd Qu.:38.55   3rd Qu.: 385.0   3rd Qu.:0.5950   3rd Qu.: 122.5  
 Max.   :47.50   Max.   :3900.0   Max.   :0.6500   Max.   :1250.0  
 densidade_kg_m3 absorção_agregado_pct
 Min.   : 238    Min.   : 0.800       
 1st Qu.:2348    1st Qu.: 1.475       
 Median :2374    Median : 1.830       
 Mean   :2350    Mean   : 1.953       
 3rd Qu.:2388    3rd Qu.: 2.100       
 Max.   :2464    Max.   :18.400       

Em relação à base original, as principais alterações foram a correção dos tipos das variáveis que estavam classificadas de forma inadequada e a remoção das observações que apresentavam valores ausentes.

Com isso, dados_sem_na apresenta uma estrutura mais adequada para as análises estatísticas seguintes, sem registros contendo NA nas variáveis analisadas. A quantidade de observações também foi reduzida em função da exclusão dos registros incompletos.

5.17 Questão 17 — Resistência média

Para avaliar o desempenho dos corpos de prova, foi calculada inicialmente a resistência média à compressão considerando todos os registros da base. Em seguida, a média foi calculada separadamente por bloco da obra, tipo de concreto e idade do corpo de prova. Para isso, foi utilizada a função aggregate(), que permite calcular estatísticas resumidas para diferentes grupos de observações.

Código
aggregate(resistencia_mpa ~ obra + tipo_concreto + idade_dias,
          data = dados_sem_na,
          FUN = mean)
      obra tipo_concreto idade_dias resistencia_mpa
1  Bloco A           C25          7        25.30000
2  Bloco C           C25          7        28.00000
3  Bloco D           C25          7        22.50000
4  Bloco A           C30          7        28.23333
5  Bloco B           C30          7        31.00000
6  Bloco C           C30          7        28.33333
7  Bloco A           C35          7        29.90000
8  Bloco C           C35          7        30.10000
9  Bloco A           C40          7        42.50000
10 Bloco C           C25         14        28.30000
11 Bloco B           C30         14        30.30000
12 Bloco C           C30         14        31.15000
13 Bloco A           C35         14        35.45000
14 Bloco B           C35         14        38.40000
15 Bloco D           C35         14        35.15000
16 Bloco B           C40         14        39.50000
17 Bloco C           C40         14        42.90000
18 Bloco D           C40         14        43.40000
19 Bloco A           C25         28        29.13333
20 Bloco B           C25         28        27.82500
21 Bloco C           C25         28        26.05000
22 Bloco D           C25         28        29.80000
23 Bloco A           C30         28        29.90000
24 Bloco B           C30         28        34.83333
25 Bloco C           C30         28        33.76000
26 Bloco D           C30         28        32.28000
27 Bloco A           C35         28        39.05000
28 Bloco B           C35         28        37.24286
29 Bloco C           C35         28        37.60000
30 Bloco D           C35         28        40.70000
31 Bloco A           C40         28        42.60000
32 Bloco B           C40         28        44.50000
33 Bloco C           C40         28        45.66667
34 Bloco D           C40         28        46.50000
35 Bloco A           C25         56        27.20000
36 Bloco C           C25         56        27.40000
37 Bloco A           C30         56        30.90000
38 Bloco B           C30         56        34.13333
39 Bloco C           C30         56        36.10000
40 Bloco B           C35         56        42.85000
41 Bloco A           C30        280        38.30000
Código
# Resistência média global
mean(dados_sem_na$resistencia_mpa)
[1] 33.82632
Código
# Resistência média por bloco
aggregate(resistencia_mpa ~ obra,
          data = dados_sem_na,
          FUN = mean)
     obra resistencia_mpa
1 Bloco A        33.42963
2 Bloco B        35.67778
3 Bloco C        32.61852
4 Bloco D        33.35000
Código
# Resistência média por tipo de concreto
aggregate(resistencia_mpa ~ tipo_concreto,
          data = dados_sem_na,
          FUN = mean)
  tipo_concreto resistencia_mpa
1           C25        27.45000
2           C30        32.07812
3           C35        37.14286
4           C40        43.33125
Código
# Resistência média por idade
aggregate(resistencia_mpa ~ idade_dias,
          data = dados_sem_na,
          FUN = mean)
  idade_dias resistencia_mpa
1          7        28.78125
2         14        35.83077
3         28        34.90000
4         56        33.11818
5        280        38.30000

O primeiro cálculo apresenta a resistência média considerando simultaneamente o bloco da obra, o tipo de concreto e a idade. Em seguida, mean() calcula a resistência média global, enquanto aggregate() permite obter as médias separadamente para cada bloco, tipo de concreto e idade.

Essa análise permite comparar o desempenho dos corpos de prova sob diferentes condições e verificar como a resistência à compressão varia entre as obras, classes de concreto e idades de ensaio.

5.18 Questão 18 — Comparação entre obras

Para identificar qual bloco da obra apresentou a maior e a menor resistência média, foram calculadas inicialmente as médias de resistência por bloco utilizando a função aggregate(). Em seguida, as funções which.max() e which.min() foram utilizadas para localizar, respectivamente, os blocos com a maior e a menor resistência média.

Código
media_obra <- aggregate(resistencia_mpa ~ obra,
                        data = dados_sem_na,
                        FUN = mean)

# Maior resistência média
media_obra[which.max(media_obra$resistencia_mpa), ]
     obra resistencia_mpa
2 Bloco B        35.67778
Código
# Menor resistência média
media_obra[which.min(media_obra$resistencia_mpa), ]
     obra resistencia_mpa
3 Bloco C        32.61852

A função aggregate() calcula a resistência média para cada bloco da obra e armazena os resultados no objeto media_obra. A função which.max() identifica a posição da maior média, enquanto which.min() identifica a posição da menor média.

Dessa forma, os códigos permitem determinar diretamente qual bloco apresentou o maior desempenho médio e qual apresentou o menor desempenho médio, utilizando como critério a resistência à compressão dos corpos de prova.

5.19 Questão 19 — Resistência média por classe de concreto

Para comparar o desempenho das diferentes classes de concreto, foi calculada a resistência média à compressão para as classes C25, C30, C35 e C40. Em seguida, foi identificada a classe que apresentou a maior resistência média.

Código
media_tipo <- aggregate(resistencia_mpa ~ tipo_concreto,
                         data = dados_sem_na,
                         FUN = mean)

# Resistência média de cada classe
media_tipo
  tipo_concreto resistencia_mpa
1           C25        27.45000
2           C30        32.07812
3           C35        37.14286
4           C40        43.33125
Código
# Classe com maior resistência média
media_tipo[which.max(media_tipo$resistencia_mpa), ]
  tipo_concreto resistencia_mpa
4           C40        43.33125

A função aggregate() calcula a resistência média para cada classe de concreto, permitindo comparar o desempenho entre C25, C30, C35 e C40. Em seguida, a função which.max() identifica a classe que apresenta a maior resistência média.

Assim, a classe apresentada no último resultado corresponde ao tipo de concreto com maior resistência média à compressão na base analisada.

5.20 Questão 20 — Utilizando aggregate()

Para analisar as características dos diferentes tipos de concreto, foram calculadas as médias de resistência à compressão, consumo de cimento, relação água/cimento, abatimento e densidade para cada classe de concreto. Para isso, foi utilizada a função aggregate().

Código
aggregate(
  cbind(resistencia_mpa,
        cimento_kg_m3,
        relacao_a_c,
        abatimento_mm,
        densidade_kg_m3) ~ tipo_concreto,
  data = dados_sem_na,
  FUN = mean
)
  tipo_concreto resistencia_mpa cimento_kg_m3 relacao_a_c abatimento_mm
1           C25        27.45000      322.3462   0.6188462      113.5769
2           C30        32.07812      461.1250   0.5678125      110.7188
3           C35        37.14286      379.2381   0.5090476      160.7143
4           C40        43.33125      404.1250   0.4775000      104.9375
  densidade_kg_m3
1        2374.000
2        2316.531
3        2363.286
4        2362.500

A função aggregate() permite calcular simultaneamente a média de várias variáveis quantitativas, agrupando os resultados pela variável tipo_concreto.

Os resultados permitem comparar as características médias das classes C25, C30, C35 e C40. A resistência média indica o desempenho mecânico de cada classe, enquanto o consumo médio de cimento mostra a quantidade de cimento utilizada por metro cúbico. A relação água/cimento permite avaliar a proporção entre água e cimento, sendo uma variável importante para o comportamento da resistência. O abatimento representa a consistência do concreto no estado fresco e a densidade indica sua massa por unidade de volume.

A comparação conjunta dessas médias permite verificar diferenças entre as classes de concreto e observar se os maiores valores de resistência estão associados a diferenças no consumo de cimento e na relação água/cimento, considerando também as características do concreto no estado fresco e endurecido.

5.21 Questão 21 — Resistência relativa

A variável resistencia_relativa foi criada para comparar a resistência à compressão observada em cada corpo de prova com a resistência de referência correspondente à sua classe de concreto.

As resistências de referência foram definidas de acordo com a classe do concreto, considerando o valor numérico indicado pela própria classificação: C25 = 25 MPa, C30 = 30 MPa, C35 = 35 MPa e C40 = 40 MPa.

Código
# Definição da resistência de referência de acordo com a classe
resistencia_referencia <- ifelse(dados_sem_na$tipo_concreto == "C25", 25,
                          ifelse(dados_sem_na$tipo_concreto == "C30", 30,
                          ifelse(dados_sem_na$tipo_concreto == "C35", 35,
                          ifelse(dados_sem_na$tipo_concreto == "C40", 40, NA))))

# Cálculo da resistência relativa
dados_sem_na$resistencia_relativa <- 
  dados_sem_na$resistencia_mpa / resistencia_referencia

# Visualização dos resultados
dados_sem_na[, c("tipo_concreto", "resistencia_mpa", "resistencia_relativa")]
    tipo_concreto resistencia_mpa resistencia_relativa
1             C35            36.3            1.0371429
2             C30            28.4            0.9466667
3             C30            36.1            1.2033333
4             C40            47.2            1.1800000
5             C25            27.9            1.1160000
6             C40            41.5            1.0375000
7             C25            23.7            0.9480000
8             C30            38.7            1.2900000
9             C30            30.3            1.0100000
10            C25            25.3            1.0120000
11            C30            31.8            1.0600000
12            C40            39.4            0.9850000
13            C35            35.6            1.0171429
14            C35            39.4            1.1257143
16            C25            28.7            1.1480000
17            C35            38.4            1.0971429
18            C30            34.7            1.1566667
19            C30            30.4            1.0133333
20            C40            41.7            1.0425000
21            C30            28.8            0.9600000
22            C40            45.2            1.1300000
23            C30            35.5            1.1833333
24            C40            44.7            1.1175000
25            C25            27.2            1.0880000
26            C25            24.4            0.9760000
27            C30            39.4            1.3133333
28            C30            33.6            1.1200000
29            C25            23.7            0.9480000
30            C35            44.6            1.2742857
31            C35            40.7            1.1628571
32            C35            36.6            1.0457143
33            C30            31.5            1.0500000
34            C30            28.7            0.9566667
35            C35            41.1            1.1742857
36            C30            24.5            0.8166667
37            C30            36.6            1.2200000
39            C40            44.9            1.1225000
40            C25            29.4            1.1760000
41            C25            31.4            1.2560000
42            C30            32.3            1.0766667
43            C35            33.9            0.9685714
44            C25            23.6            0.9440000
45            C40            42.9            1.0725000
46            C30            31.8            1.0600000
47            C25            26.2            1.0480000
48            C30            32.1            1.0700000
49            C40            38.8            0.9700000
50            C30            32.7            1.0900000
51            C30            33.1            1.1033333
52            C25            31.6            1.2640000
53            C30            27.4            0.9133333
54            C40            42.5            1.0625000
55            C25            28.2            1.1280000
56            C35            37.9            1.0828571
57            C30            33.5            1.1166667
58            C35            33.7            0.9628571
59            C30            29.9            0.9966667
60            C25            29.3            1.1720000
61            C25            29.3            1.1720000
62            C25            29.5            1.1800000
63            C35            36.2            1.0342857
64            C30            25.6            0.8533333
65            C30            35.6            1.1866667
66            C35            41.6            1.1885714
67            C30            29.6            0.9866667
68            C30            30.7            1.0233333
69            C35            33.6            0.9600000
70            C25            29.8            1.1920000
71            C30            31.0            1.0333333
72            C40            37.3            0.9325000
73            C40            46.5            1.1625000
74            C25            27.8            1.1120000
75            C35            41.8            1.1942857
76            C25            26.6            1.0640000
78            C40            46.9            1.1725000
79            C30            29.9            0.9966667
80            C35            35.1            1.0028571
81            C40            47.5            1.1875000
82            C40            43.4            1.0850000
83            C25            28.0            1.1200000
84            C25            23.3            0.9320000
85            C30            38.3            1.2766667
86            C35            30.1            0.8600000
87            C25            27.8            1.1120000
88            C35            36.9            1.0542857
89            C25            28.3            1.1320000
90            C30            33.1            1.1033333
91            C35            39.6            1.1314286
93            C40            42.9            1.0725000
94            C35            29.9            0.8542857
95            C25            30.3            1.2120000
96            C25            21.3            0.8520000
98            C35            37.0            1.0571429
99            C25            31.1            1.2440000
100           C30            30.9            1.0300000

A resistência relativa foi calculada pela expressão:

\[ R_{rel} = \frac{R_{obs}}{R_{ref}} \tag{1}\]

em que (R_{rel}) representa a resistência relativa, (R_{obs}) é a resistência observada no corpo de prova e (R_{ref}) é a resistência de referência da classe do concreto.

Valores de resistencia_relativa iguais a 1 indicam que a resistência observada corresponde à resistência de referência. Valores maiores que 1 indicam resistência superior à referência, enquanto valores menores que 1 indicam resistência inferior à referência.

A utilização dessa variável permite comparar o desempenho dos corpos de prova de diferentes classes em uma mesma escala relativa.

5.22 Questão 22 — Classificação do desempenho

Para classificar os corpos de prova, foi utilizada a variável resistencia_relativa, criada na questão anterior. O critério adotado compara a resistência observada com a resistência de referência da classe do concreto.

Foram estabelecidas duas categorias:

  • “Abaixo da referência”: resistencia_relativa < 1;
  • “Atingiu ou superou a referência”: resistencia_relativa >= 1.
Código
# Classificação dos corpos de prova
dados_sem_na$classificacao <- ifelse(
  dados_sem_na$resistencia_relativa < 1,
  "Abaixo da referência",
  "Atingiu ou superou a referência"
)

# Verificação das classificações
table(dados_sem_na$classificacao)

           Abaixo da referência Atingiu ou superou a referência 
                             23                              72 

O critério foi escolhido por permitir uma interpretação direta do desempenho em relação à resistência de referência da classe do concreto. Quando a resistência relativa é menor que 1, o corpo de prova apresenta resistência inferior ao valor de referência. Quando é igual ou superior a 1, a resistência observada atinge ou supera esse valor.

Essa classificação fornece uma forma simples de avaliar o desempenho dos corpos de prova, sem estabelecer limites adicionais que não estejam diretamente relacionados à classe do concreto.

5.23 Questão 23 — Desempenho acima da referência

Utilizando a variável resistencia_relativa criada na Questão 21, foi criada a variável acima_media para indicar se a resistência observada está acima da resistência de referência correspondente à classe do concreto.

Código
# Verificação da resistência em relação à referência da classe
dados_sem_na$acima_media <- dados_sem_na$resistencia_relativa > 1

# Visualização dos resultados
dados_sem_na[, c("tipo_concreto", "resistencia_mpa",
                 "resistencia_relativa", "acima_media")]
    tipo_concreto resistencia_mpa resistencia_relativa acima_media
1             C35            36.3            1.0371429        TRUE
2             C30            28.4            0.9466667       FALSE
3             C30            36.1            1.2033333        TRUE
4             C40            47.2            1.1800000        TRUE
5             C25            27.9            1.1160000        TRUE
6             C40            41.5            1.0375000        TRUE
7             C25            23.7            0.9480000       FALSE
8             C30            38.7            1.2900000        TRUE
9             C30            30.3            1.0100000        TRUE
10            C25            25.3            1.0120000        TRUE
11            C30            31.8            1.0600000        TRUE
12            C40            39.4            0.9850000       FALSE
13            C35            35.6            1.0171429        TRUE
14            C35            39.4            1.1257143        TRUE
16            C25            28.7            1.1480000        TRUE
17            C35            38.4            1.0971429        TRUE
18            C30            34.7            1.1566667        TRUE
19            C30            30.4            1.0133333        TRUE
20            C40            41.7            1.0425000        TRUE
21            C30            28.8            0.9600000       FALSE
22            C40            45.2            1.1300000        TRUE
23            C30            35.5            1.1833333        TRUE
24            C40            44.7            1.1175000        TRUE
25            C25            27.2            1.0880000        TRUE
26            C25            24.4            0.9760000       FALSE
27            C30            39.4            1.3133333        TRUE
28            C30            33.6            1.1200000        TRUE
29            C25            23.7            0.9480000       FALSE
30            C35            44.6            1.2742857        TRUE
31            C35            40.7            1.1628571        TRUE
32            C35            36.6            1.0457143        TRUE
33            C30            31.5            1.0500000        TRUE
34            C30            28.7            0.9566667       FALSE
35            C35            41.1            1.1742857        TRUE
36            C30            24.5            0.8166667       FALSE
37            C30            36.6            1.2200000        TRUE
39            C40            44.9            1.1225000        TRUE
40            C25            29.4            1.1760000        TRUE
41            C25            31.4            1.2560000        TRUE
42            C30            32.3            1.0766667        TRUE
43            C35            33.9            0.9685714       FALSE
44            C25            23.6            0.9440000       FALSE
45            C40            42.9            1.0725000        TRUE
46            C30            31.8            1.0600000        TRUE
47            C25            26.2            1.0480000        TRUE
48            C30            32.1            1.0700000        TRUE
49            C40            38.8            0.9700000       FALSE
50            C30            32.7            1.0900000        TRUE
51            C30            33.1            1.1033333        TRUE
52            C25            31.6            1.2640000        TRUE
53            C30            27.4            0.9133333       FALSE
54            C40            42.5            1.0625000        TRUE
55            C25            28.2            1.1280000        TRUE
56            C35            37.9            1.0828571        TRUE
57            C30            33.5            1.1166667        TRUE
58            C35            33.7            0.9628571       FALSE
59            C30            29.9            0.9966667       FALSE
60            C25            29.3            1.1720000        TRUE
61            C25            29.3            1.1720000        TRUE
62            C25            29.5            1.1800000        TRUE
63            C35            36.2            1.0342857        TRUE
64            C30            25.6            0.8533333       FALSE
65            C30            35.6            1.1866667        TRUE
66            C35            41.6            1.1885714        TRUE
67            C30            29.6            0.9866667       FALSE
68            C30            30.7            1.0233333        TRUE
69            C35            33.6            0.9600000       FALSE
70            C25            29.8            1.1920000        TRUE
71            C30            31.0            1.0333333        TRUE
72            C40            37.3            0.9325000       FALSE
73            C40            46.5            1.1625000        TRUE
74            C25            27.8            1.1120000        TRUE
75            C35            41.8            1.1942857        TRUE
76            C25            26.6            1.0640000        TRUE
78            C40            46.9            1.1725000        TRUE
79            C30            29.9            0.9966667       FALSE
80            C35            35.1            1.0028571        TRUE
81            C40            47.5            1.1875000        TRUE
82            C40            43.4            1.0850000        TRUE
83            C25            28.0            1.1200000        TRUE
84            C25            23.3            0.9320000       FALSE
85            C30            38.3            1.2766667        TRUE
86            C35            30.1            0.8600000       FALSE
87            C25            27.8            1.1120000        TRUE
88            C35            36.9            1.0542857        TRUE
89            C25            28.3            1.1320000        TRUE
90            C30            33.1            1.1033333        TRUE
91            C35            39.6            1.1314286        TRUE
93            C40            42.9            1.0725000        TRUE
94            C35            29.9            0.8542857       FALSE
95            C25            30.3            1.2120000        TRUE
96            C25            21.3            0.8520000       FALSE
98            C35            37.0            1.0571429        TRUE
99            C25            31.1            1.2440000        TRUE
100           C30            30.9            1.0300000        TRUE

A variável assume TRUE quando a resistência observada é superior à resistência de referência da classe e FALSE quando é igual ou inferior a ela.

Assim, por exemplo, um corpo de prova de C30 apresenta TRUE quando sua resistência é superior a 30 MPa, pois sua resistencia_relativa será maior que 1.

5.24 Questão 24 — Aplicação da função split()

A função split() foi utilizada para dividir a base de dados em grupos de acordo com a variável tipo_concreto. Dessa forma, cada classe de concreto é separada em um grupo independente, permitindo realizar análises específicas para cada tipo.

Para realizar a divisão, foi utilizada a base dados_sem_na, que contém apenas as observações completas após o tratamento dos dados.

Código
# Divisão da base por tipo de concreto

dados_por_tipo <- split(

  dados_sem_na,

  dados_sem_na$tipo_concreto

)

# Verificação dos grupos criados

names(dados_por_tipo)
[1] "C25" "C30" "C35" "C40"
Código
# Contagem do número de observações em cada grupo

sapply(dados_por_tipo, nrow)
C25 C30 C35 C40 
 26  32  21  16 

A função split() recebe a base de dados como primeiro argumento e a variável utilizada para definir os grupos como segundo argumento. Nesse caso, tipo_concreto determina a separação dos dados.

O resultado é armazenado no objeto dados_por_tipo, que passa a ser uma lista contendo um grupo para cada classe de concreto. Assim, os registros classificados como C25 ficam em um grupo, os registros C30 em outro, e assim sucessivamente.

A função names() permite verificar quais grupos foram criados, enquanto sapply() aplica a função nrow() a cada elemento da lista. Como nrow() retorna o número de linhas de uma base, o resultado corresponde ao número de observações existentes em cada tipo de concreto.

Para apresentar a quantidade de observações de forma mais organizada, pode-se utilizar:

Código
# Quantidade de observações por tipo de concreto

quantidade_por_tipo <- sapply(

  dados_por_tipo,

  nrow

)

quantidade_por_tipo
C25 C30 C35 C40 
 26  32  21  16 

O resultado apresenta a quantidade de corpos de prova pertencentes a cada classe de concreto. Dessa forma, é possível verificar se os grupos C25, C30, C35 e C40 possuem a mesma quantidade de observações ou se existe diferença no número de registros entre eles.

A utilização do split() é importante porque permite organizar a base em subconjuntos independentes, facilitando a aplicação posterior de outras funções do Base R. Essa estrutura será utilizada na Questão 25, na qual será calculada a resistência média de cada tipo de concreto utilizando a função lapply().

Portanto, o split() não realiza nenhum cálculo estatístico por si só. Sua função principal nesta etapa é separar os dados de acordo com uma variável categórica, criando uma estrutura que facilita o processamento individual de cada grupo.

5.25 Questão 25 — Aplicação da função lapply()

Utilizando a estrutura criada na questão anterior com a função split(), foi calculada a resistência média à compressão de cada tipo de concreto. Para isso, foi utilizada a função lapply(), que permite aplicar uma mesma função a cada grupo armazenado na lista dados_por_tipo.

Código
# Cálculo da resistência média de cada tipo de concreto

media_resistencia_tipo <- lapply(

  dados_por_tipo,

  function(x) mean(x$resistencia_mpa)

)

# Visualização dos resultados

media_resistencia_tipo
$C25
[1] 27.45

$C30
[1] 32.07812

$C35
[1] 37.14286

$C40
[1] 43.33125

A função lapply() percorre cada elemento da lista dados_por_tipo. Em cada grupo, a expressão x$resistencia_mpa seleciona a variável de resistência e a função mean() calcula sua média.

O resultado é uma lista, na qual cada elemento corresponde a um tipo de concreto. Assim, são obtidas separadamente as resistências médias dos concretos C25, C30, C35 e C40.

Para visualizar os resultados de forma mais organizada, pode-se utilizar:

Código
# Apresentação das médias por tipo de concreto

data.frame(

  tipo_concreto = names(media_resistencia_tipo),

  resistencia_media_mpa = unlist(media_resistencia_tipo)

)
    tipo_concreto resistencia_media_mpa
C25           C25              27.45000
C30           C30              32.07812
C35           C35              37.14286
C40           C40              43.33125

A tabela resultante permite comparar diretamente a resistência média das diferentes classes de concreto.

A utilização do lapply() é adequada porque a função aplica a mesma operação a cada grupo, evitando a necessidade de calcular manualmente a média de cada classe. Além disso, como os grupos foram previamente criados com split(), o código mantém uma sequência lógica: primeiro os dados são separados por tipo de concreto e, posteriormente, a resistência média é calculada individualmente para cada grupo.

Portanto, nesta questão, o split() foi responsável por organizar a base em grupos, enquanto o lapply() foi utilizado para aplicar o cálculo da média de resistência a cada um desses grupos. O resultado servirá de base para a Questão 26, na qual a mesma operação será realizada utilizando sapply().

5.26 Questão 26 — Aplicação da função sapply()

Nesta questão, a operação realizada anteriormente com lapply() foi repetida utilizando a função sapply(). O objetivo é calcular novamente a resistência média de cada tipo de concreto, utilizando a estrutura dados_por_tipo criada com split().

Código
# Cálculo da resistência média de cada tipo de concreto

media_resistencia_tipo_sapply <- sapply(

  dados_por_tipo,

  function(x) mean(x$resistencia_mpa)

)

# Visualização dos resultados

media_resistencia_tipo_sapply
     C25      C30      C35      C40 
27.45000 32.07812 37.14286 43.33125 

A função sapply() percorre cada grupo armazenado em dados_por_tipo e aplica a função mean() à variável resistencia_mpa. Dessa forma, são calculadas as médias de resistência para cada classe de concreto.

Para apresentar os resultados de forma organizada:

Código
# Organização dos resultados em tabela

data.frame(

  tipo_concreto = names(media_resistencia_tipo_sapply),

  resistencia_media_mpa = as.numeric(media_resistencia_tipo_sapply)

)
  tipo_concreto resistencia_media_mpa
1           C25              27.45000
2           C30              32.07812
3           C35              37.14286
4           C40              43.33125

O resultado permite comparar diretamente a resistência média dos concretos C25, C30, C35 e C40.

Diferença entre lapply() e sapply():

Embora as duas funções realizem a mesma operação neste caso, existe uma diferença importante na estrutura do resultado produzido.

A função lapply() sempre retorna uma lista, mantendo cada resultado como um elemento separado:

Código
# Resultado utilizando lapply()

media_resistencia_tipo_lapply <- lapply(

  dados_por_tipo,

  function(x) mean(x$resistencia_mpa)

)

media_resistencia_tipo_lapply
$C25
[1] 27.45

$C30
[1] 32.07812

$C35
[1] 37.14286

$C40
[1] 43.33125

Já a função sapply() tenta simplificar automaticamente o resultado. Como neste caso cada grupo produz apenas um único valor numérico, os resultados podem ser organizados em um vetor numérico nomeado:

Código
# Resultado utilizando sapply()

media_resistencia_tipo_sapply
     C25      C30      C35      C40 
27.45000 32.07812 37.14286 43.33125 

Assim, a diferença pode ser resumida da seguinte forma:

Função Resultado principal Característica
lapply() Lista Mantém os resultados separados em uma lista
sapply() Vetor Tenta simplificar a lista para uma estrutura mais simples

Portanto, os valores calculados são os mesmos, mas a forma como o R apresenta e armazena os resultados é diferente. O lapply() é mais apropriado quando se deseja preservar uma estrutura de lista, enquanto o sapply() é mais conveniente quando os resultados podem ser simplificados para um vetor ou matriz.

Neste caso específico, como cada tipo de concreto gera apenas uma resistência média, o sapply() produz um resultado mais compacto e fácil de visualizar. Já o lapply() mantém explicitamente a estrutura de lista criada a partir dos grupos.

Dessa forma, ambas as funções são adequadas para o cálculo solicitado, mas o sapply() oferece uma apresentação mais simples dos resultados quando todos os grupos retornam um único valor.

5.27 Questão 27 — Aplicação da função apply() para médias

Para calcular a média das principais propriedades do concreto, foram selecionadas as variáveis quantitativas resistencia_mpa, cimento_kg_m3, relacao_a_c, abatimento_mm, densidade_kg_m3 e absorção_agregado_pct. Em seguida, foi utilizada a função apply() para calcular a média de cada variável.

Código
# Seleção das variáveis quantitativas relacionadas às propriedades do concreto
propriedades_concreto <- dados_sem_na[, c(
  "resistencia_mpa",
  "cimento_kg_m3",
  "relacao_a_c",
  "abatimento_mm",
  "densidade_kg_m3",
  "absorção_agregado_pct"
)]

# Cálculo da média de cada variável
apply(propriedades_concreto, 2, mean)
      resistencia_mpa         cimento_kg_m3           relacao_a_c 
           33.8263158           395.4421053             0.5535789 
        abatimento_mm       densidade_kg_m3 absorção_agregado_pct 
          121.5789474          2350.3368421             1.9534737 

A função apply() foi aplicada sobre as colunas da base, utilizando o argumento 2, que indica que a função mean() deve ser aplicada a cada coluna.

Dessa forma, o resultado apresenta a média de cada propriedade quantitativa selecionada, permitindo obter uma caracterização geral dos concretos analisados.

5.28 Questão 28 — Aplicação da função apply() por observação

Nesta etapa, foi utilizada a função apply() para calcular, para cada corpo de prova, a média das variáveis quantitativas relacionadas às propriedades do concreto.

Código
# Cálculo da média das propriedades para cada observação
media_observacao <- apply(
  propriedades_concreto,
  1,
  mean
)

# Visualização dos resultados
media_observacao
        1         2         3         4         5         6         7         8 
 479.5167  478.9650  484.9250  490.6067  487.9700  477.1217  476.7550  481.7617 
        9        10        11        12        13        14        16        17 
 472.1267  480.4733  473.7317  487.6333  479.8150  488.0183  476.1383  476.7200 
       18        19        20        21        22        23        24        25 
 485.4800  471.8133  490.1400  493.1233  488.2667  474.1450  492.0150  470.0600 
       26        27        28        29        30        31        32        33 
 468.3367  487.0117  467.8850  467.2367  488.8483  485.6650  673.7100  480.6833 
       34        35        36        37        39        40        41        42 
 471.6983  475.2717  474.7417  484.4267  492.8217  477.8500  473.5567  479.7000 
       43        44        45        46        47        48        49        50 
 465.2867  479.4717  484.9283  490.1350  460.3117  483.8400  488.9600  479.3767 
       51        52        53        54        55        56        57        58 
 464.0983  466.4517  118.9667  483.5200  483.0983  482.1183  477.1850  480.3317 
       59        60        61        62        63        64        65        66 
 475.7633  472.4600  465.5033  470.5233  480.0517 1078.0750  472.5583  484.0383 
       67        68        69        70        71        72        73        74 
 477.7883  494.0883  484.7950  479.1817  478.4900  495.1967  474.0000  470.3583 
       75        76        78        79        80        81        82        83 
 477.9100  481.8217  474.1533  476.7633  497.8333  493.4550  483.7767  466.4350 
       84        85        86        87        88        89        90        91 
 468.5467  483.4600  469.8467  482.7700  478.7617  470.5167  497.2533  477.3183 
       93        94        95        96        98        99       100 
 485.1617  483.9833  469.5800  464.1017  489.7500  476.7667  477.4300 

O argumento 1 indica que a função deve ser aplicada por linha, ou seja, para cada observação. Assim, mean() calcula uma média envolvendo as seis variáveis quantitativas selecionadas.

Entretanto, essa medida não possui necessariamente uma interpretação física direta. Isso ocorre porque as variáveis utilizadas possuem unidades e significados diferentes, como MPa, kg/m³, mm, porcentagem e uma razão adimensional.

Portanto, embora a média possa ser calculada matematicamente, seu resultado não representa diretamente uma propriedade física do concreto. Nesse caso, a medida deve ser entendida apenas como um resumo numérico das variáveis selecionadas, e não como uma grandeza física com significado técnico específico.

5.29 Questão 29 — Aplicação de for e if

Nesta etapa, foi utilizada uma estrutura de repetição for em conjunto com a estrutura condicional if para percorrer as observações da base e identificar os corpos de prova cuja resistência à compressão está acima da resistência média de sua respectiva classe de concreto.

Para cada observação, a classe do concreto é identificada e sua resistência individual é comparada com a resistência média correspondente àquela classe.

Código
# Cálculo da resistência média de cada tipo de concreto
media_tipo <- aggregate(
  resistencia_mpa ~ tipo_concreto,
  data = dados_sem_na,
  FUN = mean
)

# Vetor vazio para armazenar os corpos de prova
# que apresentam resistência acima da média de sua classe
acima_da_media <- character(0)

# Percorrendo todas as observações da base
for (i in 1:nrow(dados_sem_na)) {
  
  # Identificação do tipo de concreto da observação
  tipo <- dados_sem_na$tipo_concreto[i]
  
  # Localização da resistência média do respectivo tipo
  media <- media_tipo$resistencia_mpa[
    media_tipo$tipo_concreto == tipo
  ]
  
  # Comparação da resistência do corpo de prova com a média
  if (dados_sem_na$resistencia_mpa[i] > media) {
    
    # Armazenamento do identificador do corpo de prova
    acima_da_media <- c(
      acima_da_media,
      dados_sem_na$id_corpo_prova[i]
    )
  }
}

# Identificação dos registros completos
# que apresentam resistência acima da média de sua classe
resultado_q29 <- dados_sem_na[
  dados_sem_na$id_corpo_prova %in% acima_da_media,
]

# Apresentação dos resultados
resultado_q29
   id_corpo_prova    obra tipo_concreto idade_dias resistencia_mpa
3          CP-003 Bloco C           C30         56            36.1
4          CP-004 Bloco A           C40         28            47.2
5          CP-005 Bloco B           C25         28            27.9
8          CP-008 Bloco D           C30         28            38.7
14         CP-014 Bloco B           C35         28            39.4
16         CP-016 Bloco A           C25         28            28.7
17         CP-017 Bloco B           C35         14            38.4
18         CP-018 Bloco B           C30         28            34.7
22         CP-022 Bloco C           C40         28            45.2
23         CP-023 Bloco C           C30         28            35.5
24         CP-024 Bloco A           C40         28            44.7
27         CP-027 Bloco B           C30         28            39.4
28         CP-028 Bloco D           C30         28            33.6
30         CP-030 Bloco B           C35         56            44.6
31         CP-031 Bloco D           C35         28            40.7
35         CP-035 Bloco B           C35         56            41.1
37         CP-037 Bloco B           C30         56            36.6
39         CP-039 Bloco C           C40         28            44.9
40         CP-040 Bloco B           C25         28            29.4
41         CP-041 Bloco D           C25         28            31.4
42         CP-042 Bloco B           C30         56            32.3
48         CP-048 Bloco B           C30          7            32.1
50         CP-050 Bloco C           C30         14            32.7
51         CP-051 Bloco C           C30         28            33.1
52         CP-052 Bloco C           C25          7            31.6
55         CP-055 Bloco D           C25         28            28.2
56         CP-056 Bloco B           C35         28            37.9
57         CP-057 Bloco B           C30         56            33.5
60         CP-060 Bloco A           C25         28            29.3
61         CP-061 Bloco C           C25         28            29.3
62         CP-062 Bloco A           C25         28            29.5
65         CP-065 Bloco C           C30         28            35.6
66         CP-066 Bloco C           C35         28            41.6
70         CP-070 Bloco A           C25         28            29.8
73         CP-073 Bloco D           C40         28            46.5
74         CP-074 Bloco B           C25         28            27.8
75         CP-075 Bloco A           C35         28            41.8
78         CP-078 Bloco C           C40         28            46.9
81         CP-081 Bloco B           C40         28            47.5
82         CP-082 Bloco D           C40         14            43.4
83         CP-083 Bloco C           C25         28            28.0
85         CP-085 Bloco A           C30        280            38.3
87         CP-087 Bloco A           C25         56            27.8
89         CP-089 Bloco C           C25         14            28.3
90         CP-090 Bloco C           C30         28            33.1
91         CP-091 Bloco B           C35         28            39.6
95         CP-095 Bloco A           C25         28            30.3
99         CP-099 Bloco C           C25         56            31.1
   cimento_kg_m3 relacao_a_c abatimento_mm densidade_kg_m3
3            338        0.56           106            2427
4            407        0.47           142            2345
5            316        0.61           133            2448
8            347        0.54           116            2387
14           394        0.52           121            2372
16           325        0.60           175            2326
17           363        0.52           109            2348
18           344        0.56           118            2414
22           409        0.48           113            2360
23           343        0.54           101            2363
24           418        0.45           124            2363
27           365        0.57           102            2413
28           343        0.58           104            2324
30           378        0.56           122            2386
31           381        0.54           103            2387
35           381        0.50           103            2324
37           369        0.55           118            2380
39           404        0.46           120            2385
40           345        0.62            89            2401
41           317        0.61           100            2390
42           351        0.56           108            2385
48           351        0.59           127            2390
50           355        0.57           142            2344
51           352        0.55            82            2316
52           318        0.64            93            2354
55           320        0.59           143            2405
56           368        0.50           108            2376
57           341        0.59            85            2402
60           340        0.63           100            2363
61           301        0.62           103            2357
62           344        0.63            97            2350
65           353        0.57           111            2334
66           372        0.51           110            2378
70           345        0.63           117            2381
73           399        0.44            81            2315
74           300        0.62           114            2378
75           362        0.46            64            2397
78           403        0.52            83            2310
81           397        0.49           146            2368
82           402        0.46           101            2354
83           315        0.64           107            2346
85           342        0.60           141            2377
87           324        0.65           118            2424
89           323        0.56           102            2367
90           367        0.55           117            2464
91           365        0.49            86            2372
95           327        0.63           124            2334
99           332        0.62            81            2414
   absorção_agregado_pct resistencia_relativa                   classificacao
3                   1.89             1.203333 Atingiu ou superou a referência
4                   1.97             1.180000 Atingiu ou superou a referência
5                   2.31             1.116000 Atingiu ou superou a referência
8                   1.33             1.290000 Atingiu ou superou a referência
14                  1.19             1.125714 Atingiu ou superou a referência
16                  1.53             1.148000 Atingiu ou superou a referência
17                  1.40             1.097143 Atingiu ou superou a referência
18                  1.62             1.156667 Atingiu ou superou a referência
22                  1.92             1.130000 Atingiu ou superou a referência
23                  1.83             1.183333 Atingiu ou superou a referência
24                  1.94             1.117500 Atingiu ou superou a referência
27                  2.10             1.313333 Atingiu ou superou a referência
28                  2.13             1.120000 Atingiu ou superou a referência
30                  1.93             1.274286 Atingiu ou superou a referência
31                  1.75             1.162857 Atingiu ou superou a referência
35                  2.03             1.174286 Atingiu ou superou a referência
37                  2.41             1.220000 Atingiu ou superou a referência
39                  2.57             1.122500 Atingiu ou superou a referência
40                  2.08             1.176000 Atingiu ou superou a referência
41                  2.33             1.256000 Atingiu ou superou a referência
42                  1.34             1.076667 Atingiu ou superou a referência
48                  2.35             1.070000 Atingiu ou superou a referência
50                  1.99             1.090000 Atingiu ou superou a referência
51                  0.94             1.103333 Atingiu ou superou a referência
52                  1.47             1.264000 Atingiu ou superou a referência
55                  1.80             1.128000 Atingiu ou superou a referência
56                  2.31             1.082857 Atingiu ou superou a referência
57                  1.02             1.116667 Atingiu ou superou a referência
60                  1.83             1.172000 Atingiu ou superou a referência
61                  2.10             1.172000 Atingiu ou superou a referência
62                  2.01             1.180000 Atingiu ou superou a referência
65                  1.18             1.186667 Atingiu ou superou a referência
66                  2.12             1.188571 Atingiu ou superou a referência
70                  1.66             1.192000 Atingiu ou superou a referência
73                  2.06             1.162500 Atingiu ou superou a referência
74                  1.73             1.112000 Atingiu ou superou a referência
75                  2.20             1.194286 Atingiu ou superou a referência
78                  1.50             1.172500 Atingiu ou superou a referência
81                  1.74             1.187500 Atingiu ou superou a referência
82                  1.80             1.085000 Atingiu ou superou a referência
83                  1.97             1.120000 Atingiu ou superou a referência
85                  1.86             1.276667 Atingiu ou superou a referência
87                  2.17             1.112000 Atingiu ou superou a referência
89                  2.24             1.132000 Atingiu ou superou a referência
90                  1.87             1.103333 Atingiu ou superou a referência
91                  0.82             1.131429 Atingiu ou superou a referência
95                  1.55             1.212000 Atingiu ou superou a referência
99                  1.88             1.244000 Atingiu ou superou a referência
   acima_media
3         TRUE
4         TRUE
5         TRUE
8         TRUE
14        TRUE
16        TRUE
17        TRUE
18        TRUE
22        TRUE
23        TRUE
24        TRUE
27        TRUE
28        TRUE
30        TRUE
31        TRUE
35        TRUE
37        TRUE
39        TRUE
40        TRUE
41        TRUE
42        TRUE
48        TRUE
50        TRUE
51        TRUE
52        TRUE
55        TRUE
56        TRUE
57        TRUE
60        TRUE
61        TRUE
62        TRUE
65        TRUE
66        TRUE
70        TRUE
73        TRUE
74        TRUE
75        TRUE
78        TRUE
81        TRUE
82        TRUE
83        TRUE
85        TRUE
87        TRUE
89        TRUE
90        TRUE
91        TRUE
95        TRUE
99        TRUE
Código
# Quantidade de corpos de prova acima da média
length(acima_da_media)
[1] 48
Código
# Lista dos identificadores dos corpos de prova
acima_da_media
 [1] "CP-003" "CP-004" "CP-005" "CP-008" "CP-014" "CP-016" "CP-017" "CP-018"
 [9] "CP-022" "CP-023" "CP-024" "CP-027" "CP-028" "CP-030" "CP-031" "CP-035"
[17] "CP-037" "CP-039" "CP-040" "CP-041" "CP-042" "CP-048" "CP-050" "CP-051"
[25] "CP-052" "CP-055" "CP-056" "CP-057" "CP-060" "CP-061" "CP-062" "CP-065"
[33] "CP-066" "CP-070" "CP-073" "CP-074" "CP-075" "CP-078" "CP-081" "CP-082"
[41] "CP-083" "CP-085" "CP-087" "CP-089" "CP-090" "CP-091" "CP-095" "CP-099"

O código calcula inicialmente a resistência média de cada tipo de concreto utilizando aggregate(). Em seguida, o for percorre todas as observações presentes em dados_sem_na.

Para cada corpo de prova, o código identifica seu tipo_concreto e localiza a resistência média correspondente. A estrutura if compara a resistência individual com essa média. Quando a resistência observada é maior que a média de sua respectiva classe, o identificador do corpo de prova é armazenado no vetor acima_da_media.

A condição utilizada foi:

Código
dados_sem_na$resistencia_mpa[i] > media
[1] FALSE

Portanto, somente os corpos de prova que apresentam resistência estritamente superior à média de sua própria classe são selecionados.

O objeto resultado_q29 apresenta os registros completos dos corpos de prova identificados, enquanto length(acima_da_media) informa a quantidade total de observações que apresentam resistência acima da média de sua respectiva classe.

5.30 Questão 30 — Abordagem vetorizada

A questão anterior foi repetida utilizando uma abordagem vetorizada, sem for e if. A comparação é realizada simultaneamente para todas as observações.

Código
# Resistência média por tipo de concreto
media_tipo <- aggregate(
  resistencia_mpa ~ tipo_concreto,
  data = dados_sem_na,
  FUN = mean
)

# Média correspondente a cada observação
media_por_observacao <- media_tipo$resistencia_mpa[
  match(dados_sem_na$tipo_concreto,
        media_tipo$tipo_concreto)
]

# Comparação vetorizada
acima_da_media_vetor <-
  dados_sem_na$resistencia_mpa > media_por_observacao

# Corpos de prova acima da média
resultado_q30 <- dados_sem_na[acima_da_media_vetor, ]

resultado_q30
   id_corpo_prova    obra tipo_concreto idade_dias resistencia_mpa
3          CP-003 Bloco C           C30         56            36.1
4          CP-004 Bloco A           C40         28            47.2
5          CP-005 Bloco B           C25         28            27.9
8          CP-008 Bloco D           C30         28            38.7
14         CP-014 Bloco B           C35         28            39.4
16         CP-016 Bloco A           C25         28            28.7
17         CP-017 Bloco B           C35         14            38.4
18         CP-018 Bloco B           C30         28            34.7
22         CP-022 Bloco C           C40         28            45.2
23         CP-023 Bloco C           C30         28            35.5
24         CP-024 Bloco A           C40         28            44.7
27         CP-027 Bloco B           C30         28            39.4
28         CP-028 Bloco D           C30         28            33.6
30         CP-030 Bloco B           C35         56            44.6
31         CP-031 Bloco D           C35         28            40.7
35         CP-035 Bloco B           C35         56            41.1
37         CP-037 Bloco B           C30         56            36.6
39         CP-039 Bloco C           C40         28            44.9
40         CP-040 Bloco B           C25         28            29.4
41         CP-041 Bloco D           C25         28            31.4
42         CP-042 Bloco B           C30         56            32.3
48         CP-048 Bloco B           C30          7            32.1
50         CP-050 Bloco C           C30         14            32.7
51         CP-051 Bloco C           C30         28            33.1
52         CP-052 Bloco C           C25          7            31.6
55         CP-055 Bloco D           C25         28            28.2
56         CP-056 Bloco B           C35         28            37.9
57         CP-057 Bloco B           C30         56            33.5
60         CP-060 Bloco A           C25         28            29.3
61         CP-061 Bloco C           C25         28            29.3
62         CP-062 Bloco A           C25         28            29.5
65         CP-065 Bloco C           C30         28            35.6
66         CP-066 Bloco C           C35         28            41.6
70         CP-070 Bloco A           C25         28            29.8
73         CP-073 Bloco D           C40         28            46.5
74         CP-074 Bloco B           C25         28            27.8
75         CP-075 Bloco A           C35         28            41.8
78         CP-078 Bloco C           C40         28            46.9
81         CP-081 Bloco B           C40         28            47.5
82         CP-082 Bloco D           C40         14            43.4
83         CP-083 Bloco C           C25         28            28.0
85         CP-085 Bloco A           C30        280            38.3
87         CP-087 Bloco A           C25         56            27.8
89         CP-089 Bloco C           C25         14            28.3
90         CP-090 Bloco C           C30         28            33.1
91         CP-091 Bloco B           C35         28            39.6
95         CP-095 Bloco A           C25         28            30.3
99         CP-099 Bloco C           C25         56            31.1
   cimento_kg_m3 relacao_a_c abatimento_mm densidade_kg_m3
3            338        0.56           106            2427
4            407        0.47           142            2345
5            316        0.61           133            2448
8            347        0.54           116            2387
14           394        0.52           121            2372
16           325        0.60           175            2326
17           363        0.52           109            2348
18           344        0.56           118            2414
22           409        0.48           113            2360
23           343        0.54           101            2363
24           418        0.45           124            2363
27           365        0.57           102            2413
28           343        0.58           104            2324
30           378        0.56           122            2386
31           381        0.54           103            2387
35           381        0.50           103            2324
37           369        0.55           118            2380
39           404        0.46           120            2385
40           345        0.62            89            2401
41           317        0.61           100            2390
42           351        0.56           108            2385
48           351        0.59           127            2390
50           355        0.57           142            2344
51           352        0.55            82            2316
52           318        0.64            93            2354
55           320        0.59           143            2405
56           368        0.50           108            2376
57           341        0.59            85            2402
60           340        0.63           100            2363
61           301        0.62           103            2357
62           344        0.63            97            2350
65           353        0.57           111            2334
66           372        0.51           110            2378
70           345        0.63           117            2381
73           399        0.44            81            2315
74           300        0.62           114            2378
75           362        0.46            64            2397
78           403        0.52            83            2310
81           397        0.49           146            2368
82           402        0.46           101            2354
83           315        0.64           107            2346
85           342        0.60           141            2377
87           324        0.65           118            2424
89           323        0.56           102            2367
90           367        0.55           117            2464
91           365        0.49            86            2372
95           327        0.63           124            2334
99           332        0.62            81            2414
   absorção_agregado_pct resistencia_relativa                   classificacao
3                   1.89             1.203333 Atingiu ou superou a referência
4                   1.97             1.180000 Atingiu ou superou a referência
5                   2.31             1.116000 Atingiu ou superou a referência
8                   1.33             1.290000 Atingiu ou superou a referência
14                  1.19             1.125714 Atingiu ou superou a referência
16                  1.53             1.148000 Atingiu ou superou a referência
17                  1.40             1.097143 Atingiu ou superou a referência
18                  1.62             1.156667 Atingiu ou superou a referência
22                  1.92             1.130000 Atingiu ou superou a referência
23                  1.83             1.183333 Atingiu ou superou a referência
24                  1.94             1.117500 Atingiu ou superou a referência
27                  2.10             1.313333 Atingiu ou superou a referência
28                  2.13             1.120000 Atingiu ou superou a referência
30                  1.93             1.274286 Atingiu ou superou a referência
31                  1.75             1.162857 Atingiu ou superou a referência
35                  2.03             1.174286 Atingiu ou superou a referência
37                  2.41             1.220000 Atingiu ou superou a referência
39                  2.57             1.122500 Atingiu ou superou a referência
40                  2.08             1.176000 Atingiu ou superou a referência
41                  2.33             1.256000 Atingiu ou superou a referência
42                  1.34             1.076667 Atingiu ou superou a referência
48                  2.35             1.070000 Atingiu ou superou a referência
50                  1.99             1.090000 Atingiu ou superou a referência
51                  0.94             1.103333 Atingiu ou superou a referência
52                  1.47             1.264000 Atingiu ou superou a referência
55                  1.80             1.128000 Atingiu ou superou a referência
56                  2.31             1.082857 Atingiu ou superou a referência
57                  1.02             1.116667 Atingiu ou superou a referência
60                  1.83             1.172000 Atingiu ou superou a referência
61                  2.10             1.172000 Atingiu ou superou a referência
62                  2.01             1.180000 Atingiu ou superou a referência
65                  1.18             1.186667 Atingiu ou superou a referência
66                  2.12             1.188571 Atingiu ou superou a referência
70                  1.66             1.192000 Atingiu ou superou a referência
73                  2.06             1.162500 Atingiu ou superou a referência
74                  1.73             1.112000 Atingiu ou superou a referência
75                  2.20             1.194286 Atingiu ou superou a referência
78                  1.50             1.172500 Atingiu ou superou a referência
81                  1.74             1.187500 Atingiu ou superou a referência
82                  1.80             1.085000 Atingiu ou superou a referência
83                  1.97             1.120000 Atingiu ou superou a referência
85                  1.86             1.276667 Atingiu ou superou a referência
87                  2.17             1.112000 Atingiu ou superou a referência
89                  2.24             1.132000 Atingiu ou superou a referência
90                  1.87             1.103333 Atingiu ou superou a referência
91                  0.82             1.131429 Atingiu ou superou a referência
95                  1.55             1.212000 Atingiu ou superou a referência
99                  1.88             1.244000 Atingiu ou superou a referência
   acima_media
3         TRUE
4         TRUE
5         TRUE
8         TRUE
14        TRUE
16        TRUE
17        TRUE
18        TRUE
22        TRUE
23        TRUE
24        TRUE
27        TRUE
28        TRUE
30        TRUE
31        TRUE
35        TRUE
37        TRUE
39        TRUE
40        TRUE
41        TRUE
42        TRUE
48        TRUE
50        TRUE
51        TRUE
52        TRUE
55        TRUE
56        TRUE
57        TRUE
60        TRUE
61        TRUE
62        TRUE
65        TRUE
66        TRUE
70        TRUE
73        TRUE
74        TRUE
75        TRUE
78        TRUE
81        TRUE
82        TRUE
83        TRUE
85        TRUE
87        TRUE
89        TRUE
90        TRUE
91        TRUE
95        TRUE
99        TRUE

A abordagem vetorizada é mais simples, mais legível e geralmente mais eficiente que a solução com for e if, pois realiza a comparação de todas as observações simultaneamente.

A solução com for e if é útil para demonstrar estruturas de repetição e decisão, enquanto a abordagem vetorizada é mais adequada para o processamento de dados no R.

Conclusão: para esta análise, considero a abordagem vetorizada a melhor solução, por utilizar menos código e realizar o processamento de forma mais direta.

5.31 Questão 31 — Comparação entre blocos

Para verificar descritivamente a afirmação de que os concretos utilizados no Bloco C apresentam desempenho superior aos demais blocos, foi calculada a resistência média à compressão para cada obra. Também foi comparada a média do Bloco C com a média conjunta dos demais blocos.

Código
# Resistência média por bloco
media_obra <- aggregate(
  resistencia_mpa ~ obra,
  data = dados_sem_na,
  FUN = mean
)

# Média do Bloco C
media_bloco_c <- mean(
  dados_sem_na$resistencia_mpa[dados_sem_na$obra == "Bloco C"]
)

# Média dos demais blocos
media_demais <- mean(
  dados_sem_na$resistencia_mpa[dados_sem_na$obra != "Bloco C"]
)

# Resultados
media_obra
     obra resistencia_mpa
1 Bloco A        33.42963
2 Bloco B        35.67778
3 Bloco C        32.61852
4 Bloco D        33.35000
Código
media_bloco_c
[1] 32.61852
Código
media_demais
[1] 34.30588

A análise descritiva apresentou as seguintes resistências médias:

Bloco Resistência média (MPa)
Bloco A 33,43
Bloco B 35,68
Bloco C 32,62
Bloco D 33,35

A resistência média do Bloco C foi de aproximadamente 32,62 MPa, enquanto a média conjunta dos demais blocos foi de aproximadamente 34,31 MPa.

Portanto, os dados não dão suporte, em termos descritivos, à afirmação do engenheiro. O Bloco C apresentou a menor resistência média entre os quatro blocos analisados, ficando abaixo dos blocos A, B e D.

Essa conclusão é exclusivamente descritiva, baseada na comparação das médias observadas, não sendo possível afirmar, a partir dessa análise, se as diferenças são estatisticamente significativas. Além disso, fatores como classe do concreto e idade dos corpos de prova podem influenciar as diferenças observadas entre os blocos.

5.32 Questão 32 — Consumo de cimento e resistência

Para investigar a afirmação de que “quanto maior o consumo de cimento, maior tende a ser a resistência do concreto”, devem ser analisadas conjuntamente as variáveis cimento_kg_m3 e resistencia_mpa.

Código
# Análise conjunta entre consumo de cimento e resistência
dados_sem_na[, c("cimento_kg_m3", "resistencia_mpa")]
    cimento_kg_m3 resistencia_mpa
1             395            36.3
2             340            28.4
3             338            36.1
4             407            47.2
5             316            27.9
6             398            41.5
7             351            23.7
8             347            38.7
9             346            30.3
10            315            25.3
11            340            31.8
12            396            39.4
13            379            35.6
14            394            39.4
16            325            28.7
17            363            38.4
18            344            34.7
19            356            30.4
20            412            41.7
21            361            28.8
22            409            45.2
23            343            35.5
24            418            44.7
25            302            27.2
26            307            24.4
27            365            39.4
28            343            33.6
29            330            23.7
30            378            44.6
31            381            40.7
32            370            36.6
33            344            31.5
34            345            28.7
35            381            41.1
36            355            24.5
37            369            36.6
39            404            44.9
40            345            29.4
41            317            31.4
42            351            32.3
43            356            33.9
44            327            23.6
45            407            42.9
46            342            31.8
47            325            26.2
48            351            32.1
49            414            38.8
50            355            32.7
51            352            33.1
52            318            31.6
53            349            27.4
54            395            42.5
55            320            28.2
56            368            37.9
57            341            33.5
58            389            33.7
59            340            29.9
60            340            29.3
61            301            29.3
62            344            29.5
63            385            36.2
64           3900            25.6
65            353            35.6
66            372            41.6
67            337            29.6
68            346            30.7
69            390            33.6
70            345            29.8
71            352            31.0
72            403            37.3
73            399            46.5
74            300            27.8
75            362            41.8
76            325            26.6
78            403            46.9
79            365            29.9
80            386            35.1
81            397            47.5
82            402            43.4
83            315            28.0
84            312            23.3
85            342            38.3
86            385            30.1
87            324            27.8
88            405            36.9
89            323            28.3
90            367            33.1
91            365            39.6
93            402            42.9
94            385            29.9
95            327            30.3
96            295            21.3
98            375            37.0
99            332            31.1
100           377            30.9

A variável cimento_kg_m3 representa o consumo de cimento por metro cúbico de concreto, enquanto resistencia_mpa representa a resistência à compressão dos corpos de prova.

Para uma análise mais adequada, também é importante considerar relacao_a_c, tipo_concreto e idade_dias, pois essas variáveis podem influenciar a resistência e interferir na relação observada entre consumo de cimento e resistência.

Portanto, as principais variáveis a serem analisadas conjuntamente são cimento_kg_m3 e resistencia_mpa, considerando também relacao_a_c, tipo_concreto e idade_dias como variáveis de contexto.

5.33 Questão 33 — Relação água/cimento e resistência

Para investigar a relação entre a relação água/cimento e a resistência à compressão, foi calculada a correlação entre as duas variáveis.

Código
cor(
  dados_sem_na$relacao_a_c,
  dados_sem_na$resistencia_mpa
)
[1] -0.7575475

A correlação obtida foi negativa (aproximadamente -0,76), indicando que, na base analisada, maiores relações água/cimento tendem a estar associadas a menores resistências.

Esse padrão merece investigação e está de acordo com o comportamento esperado do concreto. Entretanto, a resistência também pode ser influenciada por fatores como tipo de concreto, consumo de cimento e idade.

5.34 Questão 34 — Evolução da resistência com a idade

Para comparar a resistência média dos corpos de prova em diferentes idades, foi utilizada a função aggregate().

Código
# Resistência média por idade
media_idade <- aggregate(
  resistencia_mpa ~ idade_dias,
  data = dados_sem_na,
  FUN = mean
)

# Ordenação das idades
media_idade <- media_idade[
  order(media_idade$idade_dias),
]

media_idade
  idade_dias resistencia_mpa
1          7        28.78125
2         14        35.83077
3         28        34.90000
4         56        33.11818
5        280        38.30000

Os resultados indicam uma tendência geral de aumento da resistência com o avanço da idade. Entretanto, essa evolução não é perfeitamente crescente: em algumas idades, a resistência média apresenta pequenas reduções em relação à idade anterior. Essas variações podem ocorrer devido à variabilidade dos corpos de prova, condições de cura e diferenças entre os concretos analisados.

Portanto, a tendência geral é de aumento da resistência com a idade, mas com algumas oscilações nos valores médios observados.

5.35 Questão 35 — Informações estatísticas relevantes

Para o relatório técnico, as cinco informações mais importantes são:

  1. Resistência média à compressão (MPa): indica o desempenho médio dos concretos.
  2. Resistência mínima e máxima: permite identificar a amplitude dos resultados e possíveis valores extremos.
  3. Resistência média por classe de concreto: possibilita comparar o desempenho entre C25, C30, C35 e C40.
  4. Resistência média por idade: permite acompanhar a evolução da resistência ao longo do tempo.
  5. Relação água/cimento e resistência: permite avaliar uma das principais relações que influenciam o desempenho mecânico do concreto.

Essas informações fornecem uma visão geral do desempenho, variabilidade e evolução da resistência, auxiliando o engenheiro na tomada de decisões relacionadas ao controle tecnológico.

5.36 🏆 Desafio Final

Nesta etapa final, foi desenvolvido um script integrado em R para simular a atuação de um engenheiro responsável pelo controle e tratamento de uma base de dados produzida por diferentes profissionais. Como os erros não são conhecidos previamente, o código foi organizado para realizar uma sequência de inspeção, diagnóstico, limpeza, tratamento e análise dos dados.

O objetivo é transformar a base inicialmente bruta em uma estrutura mais confiável para a realização de análises estatísticas e para a tomada de decisão na Engenharia Civil.

5.36.1 Script final

O código abaixo reúne as principais etapas desenvolvidas ao longo da atividade, utilizando funções do Base R trabalhadas em aula.


# ------------------------------------------------------------
# 1. IMPORTAÇÃO DA BASE
# ------------------------------------------------------------

dados <- read.csv("base_de_dados.csv",
                  header = TRUE,
                  sep = ";")

# Visualização inicial
head(dados)

# ------------------------------------------------------------
# 2. INSPEÇÃO INICIAL
# ------------------------------------------------------------

# Dimensões da base
dim(dados)

# Estrutura das variáveis
str(dados)

# Resumo estatístico
summary(dados)

# Tipos das variáveis
sapply(dados, class)

# ------------------------------------------------------------
# 3. IDENTIFICAÇÃO DE VALORES AUSENTES
# ------------------------------------------------------------

ausentes <- c("", " ", "NA", "N/A", "-", "null", "NULL")

# Quantidade de valores ausentes por variável
sapply(dados, function(x)
  sum(is.na(x) | x %in% ausentes, na.rm = TRUE)
)

# Localização das observações com valores ausentes
which(apply(dados, 1, function(x)
  any(is.na(x) | x %in% ausentes)
))

# ------------------------------------------------------------
# 4. IDENTIFICAÇÃO DE INCONSISTÊNCIAS
# ------------------------------------------------------------

# Categorias existentes em obra
unique(dados$obra)

# Categorias existentes em tipo_concreto
unique(dados$tipo_concreto)

# Verificação de espaços desnecessários
sapply(dados, function(x)
  sum(grepl("^ | $", x))
)

# Verificação de vírgulas decimais
sapply(dados, function(x)
  sum(grepl(",", x))
)

# ------------------------------------------------------------
# 5. VERIFICAÇÃO DE VALORES SUSPEITOS
# ------------------------------------------------------------

# Idade dos corpos de prova
dados[dados$idade_dias <= 0 |
      dados$idade_dias > 56, ]

# Resistência
dados[dados$resistencia_mpa < 20 |
      dados$resistencia_mpa > 60, ]

# Abatimento
dados[dados$abatimento_mm < 10 |
      dados$abatimento_mm > 220, ]

# Densidade
dados[dados$densidade_kg_m3 < 2000 |
      dados$densidade_kg_m3 > 2600, ]

# Relação água/cimento
dados[dados$relacao_a_c < 0.40 |
      dados$relacao_a_c > 0.70, ]

# Absorção
dados[dados$`absorção_agregado_pct` < 0 |
      dados$`absorção_agregado_pct` > 10, ]

# ------------------------------------------------------------
# 6. CRIAÇÃO DA BASE PARA LIMPEZA
# ------------------------------------------------------------

dados_limpos <- dados

# ------------------------------------------------------------
# 7. CORREÇÃO DAS VARIÁVEIS QUALITATIVAS
# ------------------------------------------------------------

# Remoção de espaços desnecessários
dados_limpos$obra <- trimws(dados_limpos$obra)

# Padronização das classes de concreto
dados_limpos$tipo_concreto <-
  toupper(trimws(dados_limpos$tipo_concreto))

# ------------------------------------------------------------
# 8. CORREÇÃO DAS VARIÁVEIS QUANTITATIVAS
# ------------------------------------------------------------

dados_limpos$idade_dias <-
  as.numeric(dados_limpos$idade_dias)

dados_limpos$resistencia_mpa <-
  as.numeric(
    gsub(",",
         ".",
         gsub("O",
              "0",
              dados_limpos$resistencia_mpa))
  )

dados_limpos$cimento_kg_m3 <-
  as.numeric(
    gsub("O",
         "0",
         dados_limpos$cimento_kg_m3)
  )

dados_limpos$relacao_a_c <-
  as.numeric(
    gsub(",",
         ".",
         dados_limpos$relacao_a_c)
  )

dados_limpos$abatimento_mm <-
  as.numeric(dados_limpos$abatimento_mm)

dados_limpos$densidade_kg_m3 <-
  as.numeric(dados_limpos$densidade_kg_m3)

dados_limpos$`absorção_agregado_pct` <-
  as.numeric(dados_limpos$`absorção_agregado_pct`)

# ------------------------------------------------------------
# 9. VERIFICAÇÃO DA BASE APÓS A LIMPEZA
# ------------------------------------------------------------

str(dados_limpos)

summary(dados_limpos)

# Verificação dos tipos
sapply(dados_limpos, class)

# ------------------------------------------------------------
# 10. TRATAMENTO DOS VALORES AUSENTES
# ------------------------------------------------------------

# Criação da base final somente com observações completas
dados_finais <-
  dados_limpos[complete.cases(dados_limpos), ]

# Número de observações após o tratamento
nrow(dados_finais)

# ------------------------------------------------------------
# 11. ESTATÍSTICAS DESCRITIVAS
# ------------------------------------------------------------

# Resistência média global
media_global <-
  mean(dados_finais$resistencia_mpa)

media_global

# Resistência mínima
min(dados_finais$resistencia_mpa)

# Resistência máxima
max(dados_finais$resistencia_mpa)

# Resistência média por obra
media_obra <-
  aggregate(resistencia_mpa ~ obra,
            data = dados_finais,
            FUN = mean)

media_obra

# Resistência média por tipo de concreto
media_tipo <-
  aggregate(resistencia_mpa ~ tipo_concreto,
            data = dados_finais,
            FUN = mean)

media_tipo

# Resistência média por idade
media_idade <-
  aggregate(resistencia_mpa ~ idade_dias,
            data = dados_finais,
            FUN = mean)

media_idade

# ------------------------------------------------------------
# 12. ANÁLISE DAS PROPRIEDADES DO CONCRETO
# ------------------------------------------------------------

aggregate(
  cbind(resistencia_mpa,
        cimento_kg_m3,
        relacao_a_c,
        abatimento_mm,
        densidade_kg_m3) ~ tipo_concreto,
  data = dados_finais,
  FUN = mean
)

# ------------------------------------------------------------
# 13. PRIMEIRA VARIÁVEL DERIVADA:
#     RESISTÊNCIA RELATIVA
# ------------------------------------------------------------

resistencia_referencia <-
  ifelse(dados_finais$tipo_concreto == "C25", 25,
  ifelse(dados_finais$tipo_concreto == "C30", 30,
  ifelse(dados_finais$tipo_concreto == "C35", 35,
  ifelse(dados_finais$tipo_concreto == "C40", 40,
         NA))))

dados_finais$resistencia_relativa <-
  dados_finais$resistencia_mpa /
  resistencia_referencia

# Visualização
dados_finais[, c("tipo_concreto",
                 "resistencia_mpa",
                 "resistencia_relativa")]

# ------------------------------------------------------------
# 14. SEGUNDA VARIÁVEL DERIVADA:
#     CLASSIFICAÇÃO DO DESEMPENHO
# ------------------------------------------------------------

dados_finais$classificacao <-
  ifelse(
    dados_finais$resistencia_relativa >= 1,
    "Atingiu ou superou a referência",
    "Abaixo da referência"
  )

table(dados_finais$classificacao)

# ------------------------------------------------------------
# 15. TERCEIRA VARIÁVEL DERIVADA:
#     DESEMPENHO ACIMA DA MÉDIA DA CLASSE
# ------------------------------------------------------------

media_tipo_2 <-
  aggregate(resistencia_mpa ~ tipo_concreto,
            data = dados_finais,
            FUN = mean)

media_por_observacao <-
  media_tipo_2$resistencia_mpa[
    match(dados_finais$tipo_concreto,
          media_tipo_2$tipo_concreto)
  ]

dados_finais$acima_media <-
  dados_finais$resistencia_mpa >
  media_por_observacao

table(dados_finais$acima_media)

# ------------------------------------------------------------
# 16. UTILIZAÇÃO DE split() E sapply()
# ------------------------------------------------------------

dados_por_tipo <-
  split(dados_finais,
        dados_finais$tipo_concreto)

# Quantidade de observações por classe
quantidade_por_tipo <-
  sapply(dados_por_tipo, nrow)

quantidade_por_tipo

# Resistência média por classe
media_resistencia_tipo <-
  sapply(
    dados_por_tipo,
    function(x)
      mean(x$resistencia_mpa)
  )

media_resistencia_tipo

# ------------------------------------------------------------
# 17. APLICAÇÃO DE apply()
# ------------------------------------------------------------

propriedades <-
  dados_finais[, c(
    "resistencia_mpa",
    "cimento_kg_m3",
    "relacao_a_c",
    "abatimento_mm",
    "densidade_kg_m3"
  )]

# Média das propriedades
apply(propriedades, 2, mean)

# ------------------------------------------------------------
# 18. RELAÇÃO ÁGUA/CIMENTO E RESISTÊNCIA
# ------------------------------------------------------------

cor(
  dados_finais$relacao_a_c,
  dados_finais$resistencia_mpa
)

# ------------------------------------------------------------
# 19. COMPARAÇÃO ENTRE BLOCOS
# ------------------------------------------------------------

media_obra

# Maior média
media_obra[
  which.max(media_obra$resistencia_mpa),
]

# Menor média
media_obra[
  which.min(media_obra$resistencia_mpa),
]

# --------------------------------------------------------------
# INFORMAÇÕES PARA AUXILIAR NO PROCESSO DECISSÓRIO DO ENGENHEIRO
# --------------------------------------------------------------

cat("RELATÓRIO RESUMIDO DO CONTROLE\n")

cat("Número de observações analisadas:",
    nrow(dados_finais), "\n")

cat("Resistência média global:",
    round(media_global, 2), "MPa\n")

cat("Menor resistência:",
    min(dados_finais$resistencia_mpa),
    "MPa\n")

cat("Maior resistência:",
    max(dados_finais$resistencia_mpa),
    "MPa\n")

cat("Bloco com maior resistência média:",
    as.character(
      media_obra$obra[
        which.max(media_obra$resistencia_mpa)
      ]
    ), "\n")

cat("Resistência média do melhor bloco:",
    round(
      max(media_obra$resistencia_mpa),
      2
    ),
    "MPa\n")

O script realiza o processamento de forma sequencial. Inicialmente, a base é importada e inspecionada para verificar suas dimensões, estrutura, tipos de variáveis e estatísticas descritivas. Em seguida, são procurados valores ausentes, erros de preenchimento, categorias despadronizadas e valores potencialmente incompatíveis com o contexto do concreto.

Na etapa de limpeza, a base original é preservada no objeto dados, enquanto uma cópia chamada dados_limpos é utilizada para as correções. As variáveis qualitativas são padronizadas com trimws() e toupper(), enquanto as variáveis quantitativas são corrigidas e convertidas para o formato numérico.

Após o tratamento, foi criada a base dados_finais, contendo apenas as observações completas. Essa base é utilizada nas análises estatísticas posteriores, evitando que valores ausentes interfiram nos cálculos.

Foram também criadas variáveis derivadas para ampliar a interpretação dos dados. A variável resistencia_relativa compara a resistência observada com a resistência de referência da classe do concreto. A variável classificacao indica se o corpo de prova atingiu ou superou essa referência. Além disso, acima_media identifica os corpos de prova cuja resistência está acima da média de sua respectiva classe.

As funções aggregate(), split(), sapply() e apply() foram utilizadas para produzir informações agrupadas e estatísticas relevantes para a análise do desempenho dos concretos.

5.36.2 Informações geradas para o engenheiro

A partir do script, podem ser obtidas informações importantes para o acompanhamento do controle tecnológico, como:

  • número de corpos de prova analisados após o tratamento;
  • resistência média global;
  • menor resistência observada;
  • maior resistência observada;
  • resistência média por bloco;
  • resistência média por classe de concreto;
  • resistência média por idade;
  • quantidade de corpos de prova por classe;
  • relação entre água/cimento e resistência;
  • quantidade de corpos de prova acima da média de sua classe;
  • quantidade de corpos de prova que atingiram ou superaram a resistência de referência.

Essas informações permitem ao engenheiro identificar diferenças de desempenho entre os blocos, acompanhar a evolução da resistência e verificar possíveis situações que mereçam investigação adicional.

5.36.3 Principal problema identificado

O principal problema encontrado na base foi a presença de inconsistências de preenchimento nas variáveis quantitativas. Alguns valores que deveriam ser numéricos foram armazenados como texto devido à utilização de vírgulas como separador decimal e à presença da letra O no lugar do número 0.

Um exemplo foi o registro 3O,4, que representa um provável erro de digitação. Como a coluna contém esse tipo de caractere, o R passa a interpretar a variável inteira como character, mesmo que a maioria dos valores seja numérica.

Também foram identificadas inconsistências nas variáveis qualitativas, como Bloco B, contendo espaço adicional, e c30, escrito com letra minúscula.

A decisão adotada foi corrigir os erros de formatação e padronização identificados, converter as variáveis quantitativas para o formato numérico e remover as observações que permaneceram incompletas após o tratamento. A base original foi preservada para garantir a rastreabilidade das alterações realizadas.

6 🧠 Considerações finais

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 estatísticos confiáveis dependem diretamente da qualidade dos dados utilizados. Erros de digitação, valores ausentes, categorias diferentes para uma mesma informação e variáveis classificadas incorretamente podem alterar médias, correlações e comparações, levando a conclusões técnicas equivocadas.

No caso analisado, um dos principais problemas foi a presença de valores quantitativos registrados como texto, principalmente devido a erros de digitação e separadores decimais inconsistentes. Esse problema alterou a forma como o R interpretou algumas variáveis e precisou ser corrigido antes da realização das análises.

A limpeza permitiu transformar a base bruta em uma estrutura mais organizada e adequada ao processamento estatístico. Dessa forma, as informações obtidas passam a oferecer maior suporte para decisões relacionadas ao controle tecnológico, desempenho dos concretos e acompanhamento da qualidade da obra.

O principal aprendizado do desafio é que o trabalho do engenheiro não consiste apenas em calcular estatísticas, mas também em verificar a qualidade dos dados antes de utilizá-los para tomar decisões. Portanto, a combinação entre conhecimento técnico da Engenharia Civil e domínio das ferramentas de análise de dados é fundamental para produzir informações confiáveis e úteis para a gestão das obras.

7 📖 Referências

ASSOCIAÇÃO BRASILEIRA DE NORMAS TÉCNICAS. ABNT NBR 9778:2005: Argamassa e concreto endurecidos — Determinação da absorção de água, índice de vazios e massa específica. Rio de Janeiro: ABNT, 2005.
___. ABNT NBR 8953:2015: Concreto para fins estruturais — Classificação pela massa específica, por grupos de resistência e consistência. Rio de Janeiro: ABNT, 2015.
___. ABNT NBR 5739:2018: Concreto — Ensaio de compressão de corpos de prova cilíndricos. Rio de Janeiro: ABNT, 2018.
___. ABNT NBR 16889:2020: Concreto — Determinação da consistência pelo abatimento do tronco de cone. Rio de Janeiro: ABNT, 2020.
BATISTA, B. D. DE O. Estatística & Probabilidade aplicada às Engenharias e Ciências. Ouro Branco, MG: [s.n.].
BATISTA, B. D. DE O.; ARTHUR, D. R básico: Coleção Estudando o Ambiente R. [s.l: s.n.]. v. 1