Autor

Leonardo Müller

Data de Publicação

14/09/2026, 00:28

1 📌 Introdução

A utilização de ferramentas computacionais para organização, processamento e análise de dados tem se tornado cada vez mais importante na Engenharia Civil. Durante a execução de obras, diferentes informações são produzidas por meio de ensaios laboratoriais, levantamentos de campo, registros de controle e acompanhamento dos serviços executados. Entretanto, antes que esses dados possam ser utilizados em análises estatísticas e na tomada de decisões, é necessário verificar sua qualidade, identificando possíveis erros, inconsistências e valores ausentes.

Nesse contexto, a linguagem R constitui uma ferramenta importante para o tratamento e a análise de dados, permitindo realizar desde operações básicas de inspeção e organização até análises estatísticas mais elaboradas. Sua aplicação possibilita compreender a estrutura de uma base de dados, identificar problemas de preenchimento, padronizar informações e obter medidas capazes de auxiliar na interpretação dos resultados.

Neste trabalho, são aplicados conceitos introdutórios da linguagem R ao processamento de uma base de dados relacionada ao controle tecnológico do concreto. A atividade envolve a inspeção da base, identificação e tratamento de inconsistências, organização dos dados e realização de análises descritivas, buscando transformar os dados brutos em informações confiáveis e úteis para a Engenharia Civil.

2 🎯 Objetivos

2.1 Objetivo geral

Aplicar a linguagem R no processamento, tratamento e análise de uma base de dados de controle tecnológico do concreto.

2.2 Objetivos específicos

  • Importar e compreender a estrutura da base de dados utilizando recursos da linguagem R;
  • Identificar valores ausentes, erros de digitação e possíveis inconsistências nos dados;
  • Realizar a limpeza e a padronização das variáveis da base; aplicar funções do Base R para manipulação, organização e processamento dos dados;
  • Obter estatísticas descritivas relacionadas às propriedades do concreto;
  • Criar novas variáveis a partir das informações disponíveis; analisar relações entre variáveis relevantes para o controle tecnológico do concreto;
  • Produzir informações que possam contribuir para a interpretação dos dados e para a tomada de decisões na Engenharia Civil.

3 📚 Fundamentação Teórica

A linguagem R é uma ferramenta voltada ao processamento, análise e representação de dados, sendo amplamente utilizada em aplicações estatísticas. Por meio de seus recursos, é possível importar e organizar bases de dados, identificar inconsistências, realizar transformações e obter informações que auxiliem na interpretação dos resultados.

Antes da realização de análises estatísticas, é fundamental verificar a qualidade dos dados, considerando aspectos como valores ausentes, erros de digitação, tipos inadequados de variáveis e falta de padronização. No R, funções como str(), summary(), subset(), aggregate(), split(), apply(), lapply() e sapply() permitem realizar diferentes etapas desse processamento.

A estatística descritiva, por sua vez, permite organizar e resumir as principais características de um conjunto de dados por meio de medidas de posição, dispersão e outras formas de representação. Como referência para esses conceitos, foram utilizados os materiais disponibilizados pelo professor Ben Deivide, que apresentam fundamentos estatísticos e sua aplicação por meio da linguagem R.

4 ⚙️ Metodologia

O trabalho foi desenvolvido utilizando a linguagem R, com ênfase nas funções disponíveis no Base R. Foi analisada uma base de dados referente ao controle tecnológico do concreto, composta por 100 observações e 10 variáveis.

Inicialmente, realizou-se a inspeção e identificação de possíveis inconsistências na base. Em seguida, os dados foram tratados e utilizados para análises descritivas, comparações entre grupos e criação de novas variáveis.

A metodologia foi organizada conforme as etapas e questões apresentadas a seguir.

4.1 Etapa 1 – Conhecendo a base

Questão 1: Importar a base de dados no R e atribuí-la ao objeto dados, verificando se a importação foi realizada corretamente.

Questão 2: Determinar quantas observações e quantas variáveis existem na base.

Questão 3: Apresentar e analisar a estrutura da base utilizando uma função apropriada do R.

Questão 4: Apresentar um resumo das variáveis e identificar informações que chamem atenção.

Questão 5: Identificar quais variáveis foram reconhecidas pelo R como quantitativas e quais foram reconhecidas como qualitativas.

Questão 6: Verificar a existência de valores ausentes, identificando sua quantidade, as variáveis e as observações em que aparecem.

4.2 Etapa 2 – Investigando problemas nos dados

Questão 7: Verificar a existência de valores potencialmente incompatíveis com o contexto da Engenharia Civil, considerando idade, resistência à compressão, abatimento, densidade, relação água/cimento e absorção.

Questão 8: Identificar possíveis erros de digitação e apresentar os registros correspondentes.

Questão 9: Verificar a padronização das categorias da variável obra.

Questão 10: Verificar a padronização das categorias da variável tipo_concreto.

Questão 11: Avaliar novamente os tipos das variáveis após a identificação dos problemas e discutir como um único valor incorreto pode alterar a interpretação de uma variável pelo R.

4.3 Etapa 3 – Limpeza da base

Questão 12: Criar uma cópia da base original denominada dados_limpos e discutir a importância de preservar os dados originais.

Questão 13: Corrigir e padronizar as variáveis qualitativas.

Questão 14: Converter para o tipo adequado as variáveis que deveriam ser quantitativas.

Questão 15: Identificar os valores ausentes e discutir o tratamento mais adequado para cada situação.

Questão 16: Avaliar novamente a estrutura e o resumo da base após a limpeza, comparando os resultados com a base original.

4.4 Etapa 4 – Explorando os dados

Questão 17: Calcular a resistência média à compressão dos corpos de prova e as médias por bloco da obra, tipo de concreto e idade.

Questão 18: Comparar as obras e identificar os blocos com maior e menor resistência média.

Questão 19: Calcular e comparar a resistência média das classes C25, C30, C35 e C40.

Questão 20: Utilizar a função aggregate() para calcular valores médios das principais propriedades para cada tipo de concreto e interpretar os resultados.

4.5 Etapa 5 – Criando novas variáveis

Questão 21: Criar a variável resistencia_relativa, relacionando a resistência observada a uma resistência de referência.

Questão 22: Criar a variável classificacao a partir de critérios relacionados à resistência.

Questão 23: Criar a variável lógica acima_media, indicando se a resistência está acima da média de seu respectivo tipo de concreto.

4.6 Etapa 6 – Utilizando split(), lapply() e sapply()

Questão 24: Dividir a base conforme o tipo de concreto utilizando split() e determinar o número de observações de cada grupo.

Questão 25: Calcular a resistência média de cada grupo utilizando lapply().

Questão 26: Repetir o procedimento utilizando sapply() e comparar os resultados das duas funções.

4.7 Etapa 7 – Utilizando apply()

Questão 27: Utilizar apply() para calcular a média das variáveis quantitativas relacionadas às propriedades do concreto.

Questão 28: Obter uma medida resumo para cada observação e discutir sua interpretação física.

4.8 Etapa 8 – Estruturas for e if

Questão 29: Utilizar for e if para identificar os corpos de prova cuja resistência esteja acima da média da respectiva classe.

Questão 30: Repetir o procedimento por meio de uma abordagem vetorizada e comparar as duas soluções quanto à simplicidade, legibilidade e eficiência.

4.9 Etapa 9 – Aplicações próximas da prática profissional

Questão 31: Avaliar, em termos descritivos, a afirmação de que os concretos utilizados no Bloco C apresentam desempenho superior aos demais.

Questão 32: Investigar a relação entre o consumo de cimento e a resistência do concreto.

Questão 33: Investigar a relação entre água/cimento e resistência à compressão.

Questão 34: Comparar a resistência média dos concretos em diferentes idades.

Questão 35: Selecionar cinco informações estatísticas consideradas relevantes para um relatório de controle tecnológico e justificar cada escolha.

4.10 Desafio Final – O engenheiro responsável pelos dados

Como etapa final, será desenvolvido um script em R reunindo os principais procedimentos realizados ao longo da atividade. O script deverá realizar a inspeção inicial da base, identificar possíveis problemas e valores ausentes, verificar inconsistências, produzir uma versão limpa dos dados, gerar estatísticas descritivas, criar pelo menos duas variáveis derivadas e fornecer informações relevantes para auxiliar o engenheiro responsável pela obra.

O código será organizado de forma lógica e compreensível, priorizando, sempre que possível, as ferramentas do Base R estudadas durante a disciplina. Ao final, será realizada uma reflexão sobre a importância do processamento e da limpeza dos dados antes da aplicação de métodos estatísticos na Engenharia Civil, bem como sobre os principais problemas encontrados e as decisões adotadas para seu tratamento.

5 🔍 Resultados e Discussão

5.1 Etapa 1 – Conhecendo a base

5.1.1 Importe a base de dados no R e atribua-a ao objeto dados.

Verifique se a importação foi realizada corretamente.

A base de dados foi importada no R e armazenada no objeto dados, através do código ’dados <- read.csv2…“. Para verificar se a importação ocorreu corretamente, foram utilizadas as funções head() e dados(), que permitiram visualizar as primeiras observações e a estrutura da base.

5.1.2 Quantas observações e quantas variáveis existem na base?

Apresente um código R que permita responder à questão.

As funcões nrow()e ncol() indicaram o número de linhas e de colunas, respectivamente. Cada linha corresponde a um corpo de prova ou registro de controle, enquanto as colunas representam as características analisadas.

5.1.3 Apresente a estrutura da base utilizando uma função apropriada do R.

Analise o resultado obtido.

Foi utilizada a função str() que possibilitou identificar o tipo de cada variável armazenada na base. Observou-se que algumas variáveis foram corretamente reconhecidas como “chr”, enquanto características como densidade, absorção do agregado, relação água cimento entre outras, foram classificadas erroneamente como “chr”, e devem ser reclassificadas como variáveis numéricas.

5.1.4 Apresente um resumo das variáveis da base.

Quais informações chamam sua atenção?

A partir da função summary(), foi possível realizar uma avaliação inicial da base e identificar alguns resultados que merecem atenção. A variável idade_dias apresentou valor máximo de 280 dias, enquanto o terceiro quartil corresponde a 28 dias. Esse valor indica claramente um provável erro de digitação e deverá ser corrigido após a identificação do respectivo registro.

Também foi observado que diversas variáveis que representam grandezas quantitativas, como resistência à compressão, consumo de cimento, relação água/cimento, abatimento, densidade e absorção do agregado, não foram reconhecidas pelo R como numéricas. Esse comportamento indica a possível presença de registros preenchidos de forma inadequada. Além disso, foram identificados valores em branco em algumas dessas variáveis.

Outro ponto relevante foi a existência de cinco categorias distintas para tipo_concreto, embora sejam previstas apenas as classes C25, C30, C35 e C40, indicando uma possível inconsistência de padronização. Esses resultados reforçam a necessidade de uma investigação e limpeza da base antes da realização das análises estatísticas.

5.1.5 Quais variáveis foram reconhecidas pelo R como quantitativas e quais foram reconhecidas como qualitativas?

Justifique sua resposta a partir da estrutura apresentada pelo R.

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        : chr  "111.0" "114.0" "106.0" "142.0" ...
 $ densidade_kg_m3      : chr  "2332.0" "2389.0" "2427.0" "2345.0" ...
 $ absorção_agregado_pct: chr  "2.3" "1.85" "1.89" "1.97" ...
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"           "character"           "character" 
absorção_agregado_pct 
          "character" 

A partir das funções str() e sapply(), verificou-se que apenas a variável idade_dias foi reconhecida pelo R como quantitativa, sendo classificada como integer. As variáveis id_corpo_prova, obra, tipo_concreto, resistencia_mpa, cimento_kg_m3, relacao_a_c, abatimento_mm, densidade_kg_m3 e absorção_agregado_pct foram reconhecidas como character.

Entretanto, resistência, consumo de cimento, relação água/cimento, abatimento, densidade e absorção do agregado representam grandezas quantitativas. Portanto, sua classificação como character indica a presença de valores ou formatações incompatíveis com o tipo numérico, que deverão ser identificados e tratados posteriormente.

5.1.6 Verifique a existência de valores ausentes na base.

Mostrar código
sapply(dados, function(x) sum(is.na(x)))
       id_corpo_prova                  obra         tipo_concreto 
                    0                     0                     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 
Mostrar código
sapply(dados, function(x) sum(x == "", 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 
Mostrar código
subset(
  dados,
  resistencia_mpa == "" |
  cimento_kg_m3 == "" |
  relacao_a_c == "" |
  abatimento_mm == "" |
  densidade_kg_m3 == "" |
  absorção_agregado_pct == ""
)
   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                
97         CP-097 Bloco A           C25         28            26.7
   cimento_kg_m3 relacao_a_c abatimento_mm densidade_kg_m3
15           363        0.49                        2359.0
38           309                     146.0          2334.0
77           307        0.63         119.0                
92           370        0.47         111.0          2380.0
97           356        0.64         122.0          2440.0
   absorção_agregado_pct
15                  1.93
38                  2.12
77                  1.38
92                  2.38
97                      
5.1.6.1 Quantos valores ausentes existem?

Foram identificados 5 valores ausentes na base de dados. Esses valores estão representados por campos vazios (""), não sendo reconhecidos diretamente pelo R como NA.

5.1.6.2 Em quais variáveis eles aparecem?

Os valores ausentes aparecem nas variáveis resistencia_mpa, relacao_a_c, abatimento_mm, densidade_kg_m3 e absorção_agregado_pct, com um campo vazio em cada variável.

5.1.6.3 Em quais observações eles aparecem?

Os valores ausentes foram identificados nas observações correspondentes aos seguintes corpos de prova: CP-015: apresenta ausência em abatimento_mm; CP-038: em relacao_a_c; CP-077: em densidade_kg_m3; CP-092: em resistencia_mpa; CP-097: em absorção_agregado_pct.

5.2 Etapa 2 — Investigando problemas nos dados

Nesta etapa, o objetivo é identificar possíveis problemas de qualidade da informação antes de realizar análises estatísticas.

5.2.1 Verifique se existem valores que parecem incompatíveis com o contexto da Engenharia Civil.

Crie códigos que permitam localizar as observações potencialmente problemáticas.

Sim, alguns valores registrados estão fora do padrão esperado para as variáveis analisadas e podem indicar erros de preenchimento. Por exemplo, foi identificada uma idade de 280 dias, muito superior às demais idades registradas na base, e um abatimento de 1250 mm, valor que apresenta uma ordem de grandeza incompatível com os demais registros. Também foram observados problemas de formatação e digitação em algumas variáveis.

Dessa forma, foram definidos critérios de verificação para identificar valores que possam ser incompatíveis com o contexto das variáveis analisadas. Para isso, foram utilizados filtros capazes de localizar idades, abatimentos, densidades, relações água/cimento e valores de absorção que apresentassem ordens de grandeza incomuns, além de registros que não pudessem ser interpretados corretamente como valores numéricos.

A aplicação desses critérios permitiu identificar observações potencialmente problemáticas, que deverão ser avaliadas individualmente antes da etapa de limpeza da base.

# Idades suspeitas
subset(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.0          2377.0
   absorção_agregado_pct
85                  1.86
# Valores de resistência que não podem ser convertidos para número
subset(dados, is.na(as.numeric(resistencia_mpa)) &
              resistencia_mpa != "")
   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
   cimento_kg_m3 relacao_a_c abatimento_mm densidade_kg_m3
8            347        0.54         116.0          2387.0
19           356        0.59          83.0          2360.0
   absorção_agregado_pct
8                   1.33
19                  0.89
# Valores de cimento que não podem ser convertidos para número
subset(dados, is.na(as.numeric(cimento_kg_m3)) &
              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.0          2427.0
   absorção_agregado_pct
64                  1.26
# Abatimentos com valor muito elevado
subset(dados, as.numeric(abatimento_mm) > 300)
   id_corpo_prova    obra tipo_concreto idade_dias resistencia_mpa
32         CP-032 Bloco D           C35         14            36.6
   cimento_kg_m3 relacao_a_c abatimento_mm densidade_kg_m3
32           370        0.53        1250.0          2383.0
   absorção_agregado_pct
32                  2.13
# Densidades muito baixas
subset(dados, as.numeric(densidade_kg_m3) < 1500)
   id_corpo_prova    obra tipo_concreto idade_dias resistencia_mpa
53         CP-053 Bloco D           C30         28            27.4
   cimento_kg_m3 relacao_a_c abatimento_mm densidade_kg_m3
53           349        0.61          97.0           238.0
   absorção_agregado_pct
53                  1.79
# Relação água/cimento que não pode ser convertida para número
subset(dados, is.na(as.numeric(relacao_a_c)) &
              relacao_a_c != "")
   id_corpo_prova    obra tipo_concreto idade_dias resistencia_mpa
45         CP-045 Bloco C           C40         14            42.9
   cimento_kg_m3 relacao_a_c abatimento_mm densidade_kg_m3
45           407        0,55          76.0          2381.0
   absorção_agregado_pct
45                  2.12
# Absorções muito elevadas
subset(dados, as.numeric(absorção_agregado_pct) > 10)
   id_corpo_prova    obra tipo_concreto idade_dias resistencia_mpa
72         CP-072 Bloco B           C40         14            37.3
   cimento_kg_m3 relacao_a_c abatimento_mm densidade_kg_m3
72           403        0.48          98.0          2414.0
   absorção_agregado_pct
72                  18.4

5.2.2 Existem valores que podem ser considerados possíveis erros de digitação?

Localize-os e apresente os respectivos registros completos.

Sim. Foram identificados possíveis erros de digitação e de padronização numérica em quatro observações da base. Os registros CP-019 e CP-064 apresentam a letra O no lugar do número 0, nas variáveis resistencia_mpa e cimento_kg_m3, respectivamente. Já os registros CP-008 e CP-045 apresentam uso de vírgula como separador decimal, diferente do padrão adotado nos demais registros da base.

Os registros completos foram localizados por meio da função subset(), permitindo identificar as observações que deverão ser corrigidas na etapa de limpeza dos dados.

5.2.3 Verifique se todas as categorias da variável obra estão escritas de forma padronizada.

Caso encontre alguma inconsistência, identifique-a.

A análise da variável obra mostrou que suas categorias não estão completamente padronizadas. Foram identificadas as categorias Bloco A, Bloco B, Bloco C e Bloco D, além de um registro denominado Bloco B, que apresenta um espaço adicional ao final do texto.

Embora Bloco B e Bloco B representem a mesma obra, o R os reconhece como categorias distintas devido à diferença na forma de escrita. Portanto, esse registro deverá ser padronizado na etapa de limpeza da base.

5.2.4 Verifique se todas as categorias de tipo_concreto estão padronizadas.

Existe alguma categoria que possa representar o mesmo tipo de concreto que outra, mas esteja escrita de maneira diferente?

Sim, existe uma categoria que representa o mesmo tipo de concreto que outra, mas está escrita de maneira diferente. A categoria c30 corresponde à classe C30, diferenciando-se apenas pelo uso de letra minúscula.

Como o R diferencia letras maiúsculas de minúsculas, c30 e C30 são interpretadas como categorias distintas. Portanto, a categoria c30 deverá ser padronizada para C30 na etapa de limpeza da base.

5.2.5 Verifique novamente os tipos das variáveis depois de identificar os problemas.

A partir da função str(), verificou-se que apenas a variável idade_dias foi reconhecida pelo R como numérica, sendo classificada como integer. As variáveis resistencia_mpa, cimento_kg_m3, relacao_a_c, abatimento_mm, densidade_kg_m3 e absorção_agregado_pct, embora representem grandezas quantitativas, foram reconhecidas como character.

Essa classificação está relacionada às inconsistências identificadas anteriormente, como erros de digitação e diferentes formas de representação dos números. A presença de um valor incompatível com o formato numérico pode fazer com que toda a variável seja interpretada pelo R como texto, mesmo que os demais registros sejam numéricos.

5.3 Etapa 3 — Limpeza da base

Nesta etapa, você deverá produzir uma versão da base destinada às análises.

5.3.1 Crie uma cópia da base original.

Por que é recomendável preservar a base original?

Mostrar código
dados_corrigidos <- dados

Foi criada uma cópia da base original denominada dados_corrigidos, que será utilizada nas etapas de correção e tratamento dos dados.

Preservar a base original é importante para manter os dados brutos disponíveis para consulta e comparação durante o processo de limpeza. Dessa forma, caso alguma correção seja realizada de maneira inadequada, é possível verificar novamente o registro original sem perder as informações inicialmente importadas.

5.3.2 Corrija os problemas encontrados nas variáveis qualitativas, de modo que suas categorias fiquem padronizadas.

Mostrar código
dados_corrigidos$obra <- ifelse(
  dados_corrigidos$obra == "Bloco B ",
  "Bloco B",
  dados_corrigidos$obra
)

dados_corrigidos$tipo_concreto <- ifelse(
  dados_corrigidos$tipo_concreto == "c30",
  "C30",
  dados_corrigidos$tipo_concreto
)

table(dados_corrigidos$obra)

Bloco A Bloco B Bloco C Bloco D 
     28      29      28      15 
Mostrar código
table(dados_corrigidos$tipo_concreto)

C25 C30 C35 C40 
 29  32  23  16 

As inconsistências identificadas anteriormente nas variáveis qualitativas foram corrigidas utilizando a função ifelse(). Na variável obra, a categoria Bloco B foi padronizada para Bloco B, enquanto na variável tipo_concreto, a categoria c30 foi corrigida para C30.

Após as correções, as categorias foram verificadas novamente, confirmando a padronização das variáveis qualitativas da base.

5.3.3 Converta para o tipo adequado as variáveis que deveriam ser quantitativas.

Verifique se a conversão foi realizada corretamente.

Mostrar código
# Correção dos registros identificados anteriormente
dados_corrigidos$idade_dias <- ifelse(
  dados_corrigidos$idade_dias == 280, 28,
  dados_corrigidos$idade_dias
)

dados_corrigidos$resistencia_mpa <- ifelse(
  dados_corrigidos$resistencia_mpa == "3O,4", "30.4",
  ifelse(dados_corrigidos$resistencia_mpa == "38,7", "38.7",
         dados_corrigidos$resistencia_mpa)
)

dados_corrigidos$cimento_kg_m3 <- ifelse(
  dados_corrigidos$cimento_kg_m3 == "390O", "390",
  dados_corrigidos$cimento_kg_m3
)

dados_corrigidos$relacao_a_c <- ifelse(
  dados_corrigidos$relacao_a_c == "0,55", "0.55",
  dados_corrigidos$relacao_a_c
)

dados_corrigidos$abatimento_mm <- ifelse(
  dados_corrigidos$abatimento_mm == "1250.0", "125.0",
  dados_corrigidos$abatimento_mm
)

dados_corrigidos$densidade_kg_m3 <- ifelse(
  dados_corrigidos$densidade_kg_m3 == "238.0", "2380.0",
  dados_corrigidos$densidade_kg_m3
)

dados_corrigidos$absorção_agregado_pct <- ifelse(
  dados_corrigidos$absorção_agregado_pct == "18.4", "1.84",
  dados_corrigidos$absorção_agregado_pct
)

# Conversão das variáveis quantitativas
dados_corrigidos$resistencia_mpa <- as.numeric(dados_corrigidos$resistencia_mpa)
dados_corrigidos$cimento_kg_m3 <- as.numeric(dados_corrigidos$cimento_kg_m3)
dados_corrigidos$relacao_a_c <- as.numeric(dados_corrigidos$relacao_a_c)
dados_corrigidos$abatimento_mm <- as.numeric(dados_corrigidos$abatimento_mm)
dados_corrigidos$densidade_kg_m3 <- as.numeric(dados_corrigidos$densidade_kg_m3)
dados_corrigidos$absorção_agregado_pct <- as.numeric(dados_corrigidos$absorção_agregado_pct)

# Verificação dos tipos
str(dados_corrigidos)
'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 ...

Inicialmente, foram corrigidos os registros identificados anteriormente como erros de digitação, formatação ou ordem de grandeza. Em seguida, as variáveis referentes à resistência à compressão, consumo de cimento, relação água/cimento, abatimento, densidade e absorção do agregado foram convertidas para o tipo numérico utilizando a função as.numeric().

A conversão foi verificada por meio da função str(), que confirmou que todas as variáveis quantitativas passaram a ser reconhecidas como numéricas. Dessa forma, a base está adequada para a realização das operações e análises estatísticas posteriores.

5.3.4 Identifique os valores ausentes. Discuta qual procedimento seria mais adequado para cada situação:

excluir a observação; substituir o valor; manter o NA; consultar a fonte original dos dados. Justifique suas decisões.

Foram identificados cinco valores ausentes na base corrigida, presentes nas variáveis abatimento_mm, relacao_a_c, densidade_kg_m3, resistencia_mpa e absorção_agregado_pct, correspondentes aos corpos de prova CP-015, CP-038, CP-077, CP-092 e CP-097, respectivamente.

A exclusão completa dessas observações não é adequada, pois cada registro apresenta apenas uma informação ausente, enquanto todas as demais permanecem disponíveis e podem ser utilizadas nas análises. Excluir o corpo de prova inteiro significaria descartar diversos dados válidos devido à ausência de apenas uma variável.

Da mesma forma, não é recomendável substituir os valores ausentes pela média neste caso. Embora a média possa ser uma alternativa viável para o tratamento de valores ausentes em outros tipos de dados e situações, sua utilização deve considerar a natureza da variável analisada. Nesta base, variáveis como resistência à compressão e relação água/cimento representam características específicas de cada corpo de prova e estão relacionadas a outras propriedades do concreto. Dessa forma, substituir um valor ausente pela média dos demais registros poderia atribuir ao corpo de prova uma característica que não corresponde ao seu valor real, além de reduzir artificialmente a variabilidade da base e influenciar análises posteriores.

Assim, o procedimento mais adequado seria consultar inicialmente a fonte original dos dados para tentar recuperar as informações. Caso isso não seja possível, os valores serão mantidos como NA e tratados adequadamente nas análises estatísticas posteriores.

5.3.5 Depois da limpeza, verifique novamente:

str(dados_limpos) summary(dados_limpos)

O que mudou em relação à base original?

Mostrar código
str(dados_corrigidos)
'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 ...
Mostrar código
summary(dados_corrigidos)
   id_corpo_prova        obra       tipo_concreto   idade_dias   
 Length   :100    Length   :100   Length   :100   Min.   : 7.00  
 N.unique :100    N.unique :  4   N.unique :  4   1st Qu.:14.00  
 N.blank  :  0    N.blank  :  0   N.blank  :  0   Median :28.00  
 Min.nchar:  6    Min.nchar:  7   Min.nchar:  3   Mean   :25.48  
 Max.nchar:  6    Max.nchar:  7   Max.nchar:  3   3rd Qu.:28.00  
                                                  Max.   :56.00  
                                                                 
 resistencia_mpa cimento_kg_m3    relacao_a_c     abatimento_mm  
 Min.   :19.00   Min.   :295.0   Min.   :0.4300   Min.   : 64.0  
 1st Qu.:28.75   1st Qu.:339.5   1st Qu.:0.5100   1st Qu.: 99.5  
 Median :32.30   Median :354.0   Median :0.5600   Median :110.0  
 Mean   :33.55   Mean   :357.6   Mean   :0.5537   Mean   :110.3  
 3rd Qu.:38.35   3rd Qu.:385.0   3rd Qu.:0.6000   3rd Qu.:122.5  
 Max.   :47.50   Max.   :418.0   Max.   :0.6500   Max.   :175.0  
 NAs    :1                       NAs    :1        NAs    :1      
 densidade_kg_m3 absorção_agregado_pct
 Min.   :2293    Min.   :0.800        
 1st Qu.:2348    1st Qu.:1.475        
 Median :2374    Median :1.840        
 Mean   :2373    Mean   :1.786        
 3rd Qu.:2388    3rd Qu.:2.100        
 Max.   :2464    Max.   :2.920        
 NAs    :1       NAs    :1            

Após a limpeza, foram observadas mudanças significativas na estrutura e no resumo da base. As variáveis quantitativas que anteriormente estavam classificadas como character passaram a ser corretamente reconhecidas como numéricas, permitindo o cálculo de medidas como média, mediana, quartis, valores mínimos e máximos.

As inconsistências identificadas anteriormente também foram corrigidas. As variáveis obra e tipo_concreto passaram a apresentar quatro categorias cada, eliminando as diferenças de padronização. Além disso, os valores incompatíveis identificados nas variáveis quantitativas foram corrigidos, como pode ser observado na idade máxima de 56 dias, no abatimento máximo de 175 mm, na densidade mínima de 2293 kg/m³ e na absorção máxima de 2,92%.

Os cinco campos vazios identificados na base original passaram a ser representados adequadamente como NA. Dessa forma, a base corrigida apresenta estrutura mais consistente e adequada para a realização das análises estatísticas das etapas seguintes.

5.4 Etapa 4 — Explorando os dados

Agora que a base foi inspecionada e tratada, utilize as ferramentas de manipulação e processamento estudadas em aula.

5.4.1 Calcule a resistência média à compressão dos corpos de prova.

Calcule também a resistência média por: bloco da obra; tipo de concreto; idade do corpo de prova.

Mostrar código
# Resistência média geral
mean(dados_corrigidos$resistencia_mpa, na.rm = TRUE)
[1] 33.54747
Mostrar código
# Resistência média por obra
tapply(
  dados_corrigidos$resistencia_mpa,
  dados_corrigidos$obra,
  mean,
  na.rm = TRUE
)
 Bloco A  Bloco B  Bloco C  Bloco D 
33.18929 35.70000 32.37143 32.39333 
Mostrar código
# Resistência média por tipo de concreto
tapply(
  dados_corrigidos$resistencia_mpa,
  dados_corrigidos$tipo_concreto,
  mean,
  na.rm = TRUE
)
     C25      C30      C35      C40 
27.07241 32.07812 37.10455 43.33125 
Mostrar código
# Resistência média por idade
tapply(
  dados_corrigidos$resistencia_mpa,
  dados_corrigidos$idade_dias,
  mean,
  na.rm = TRUE
)
       7       14       28       56 
28.78125 34.74000 34.65439 33.11818 
Mostrar código
# Resistência média por tipo de concreto e idade
tapply(
  dados_corrigidos$resistencia_mpa,
  list(
    dados_corrigidos$tipo_concreto,
    dados_corrigidos$idade_dias
  ),
  mean,
  na.rm = TRUE
)
          7       14       28    56
C25 25.2600 23.65000 27.90556 27.30
C30 28.9625 30.86667 33.30000 33.88
C35 30.0000 35.98333 37.89167 42.85
C40 42.5000 41.32500 44.13636    NA

A resistência média geral dos corpos de prova foi de aproximadamente 33,55 MPa. Na análise por obra, o Bloco B apresentou a maior resistência média, com 35,70 MPa, enquanto os demais blocos apresentaram valores próximos, variando entre aproximadamente 32,37 e 33,19 MPa.

Em relação ao tipo de concreto, observou-se aumento progressivo da resistência média conforme a classe, sendo obtidos 27,07 MPa para C25, 32,08 MPa para C30, 37,10 MPa para C35 e 43,33 MPa para C40.

Na análise por idade, foram obtidas resistências médias de 28,78 MPa aos 7 dias, 34,74 MPa aos 14 dias, 34,65 MPa aos 28 dias e 33,12 MPa aos 56 dias. Entretanto, esses valores agrupam corpos de prova pertencentes a diferentes classes de concreto. Dessa forma, a redução observada na média geral aos 56 dias não deve ser interpretada diretamente como uma redução da resistência com o aumento da idade.

Para complementar a análise, a resistência média foi calculada considerando simultaneamente o tipo de concreto e a idade. Para o C30, a resistência média aumentou de 28,96 MPa aos 7 dias para 33,88 MPa aos 56 dias, enquanto para o C35 passou de 30,00 MPa para 42,85 MPa no mesmo intervalo, indicando uma tendência de aumento da resistência com a idade. O C25 apresentou maior oscilação entre as idades, enquanto para o C40 não existem dados aos 56 dias.

Portanto, a análise conjunta demonstra que a interpretação da resistência em função da idade se torna mais adequada quando também é considerada a classe do concreto. As diferenças na composição dos grupos podem influenciar as médias gerais por idade, sendo necessário considerar essas características antes de atribuir as variações observadas exclusivamente ao tempo de cura.

5.4.2 Qual bloco da obra apresentou a maior resistência média? Qual apresentou a menor?

Apresente os códigos utilizados para responder à questão.

Mostrar código
tapply(
  dados_corrigidos$resistencia_mpa,
  dados_corrigidos$obra,
  mean,
  na.rm = TRUE
)
 Bloco A  Bloco B  Bloco C  Bloco D 
33.18929 35.70000 32.37143 32.39333 

A partir das resistências médias calculadas para cada obra, verificou-se que o Bloco B apresentou a maior resistência média, com 35,70 MPa, enquanto o Bloco C apresentou a menor resistência média, com aproximadamente 32,37 MPa.

Os Blocos A e D apresentaram médias de aproximadamente 33,19 MPa e 32,39 MPa, respectivamente. Destaca-se ainda que os resultados dos Blocos C e D são bastante próximos entre si.

5.4.3 Calcule a resistência média para cada classe de concreto (C25;C30;C35;C40). Qual classe apresentou a maior resistência média?

Mostrar código
tapply(
  dados_corrigidos$resistencia_mpa,
  dados_corrigidos$tipo_concreto,
  mean,
  na.rm = TRUE
)
     C25      C30      C35      C40 
27.07241 32.07812 37.10455 43.33125 

As resistências médias obtidas foram de aproximadamente 27,07 MPa para o C25, 32,08 MPa para o C30, 37,10 MPa para o C35 e 43,33 MPa para o C40.

Dentre as classes analisadas, o C40 apresentou a maior resistência média, com aproximadamente 43,33 MPa. Observa-se também um aumento progressivo da resistência média conforme o aumento da classe de resistência do concreto, indicando coerência entre a classificação dos concretos e os resultados obtidos nos ensaios.

5.4.4 Utilizando aggregate(), obtenha a média das seguintes variáveis para cada tipo de concreto: (resistência;,consumo de cimento;relação água/cimento;abatimento;densidade.

Interprete os resultados obtidos.

Mostrar código
aggregate(
  cbind(
    resistencia_mpa,
    cimento_kg_m3,
    relacao_a_c,
    abatimento_mm,
    densidade_kg_m3
  ) ~ tipo_concreto,
  data = dados_corrigidos,
  FUN = mean,
  na.rm = TRUE
)
  tipo_concreto resistencia_mpa cimento_kg_m3 relacao_a_c abatimento_mm
1           C25        27.42222      323.5926   0.6196296      113.8889
2           C30        32.07812      351.4375   0.5678125      110.7188
3           C35        37.14286      379.2381   0.5090476      107.1429
4           C40        43.33125      404.1250   0.4775000      104.9375
  densidade_kg_m3
1        2376.444
2        2383.469
3        2363.286
4        2362.500

Os resultados obtidos mostram diferenças consistentes entre as classes de concreto. A resistência média apresentou crescimento conforme o aumento da classe, passando de aproximadamente 27,42 MPa no C25 para 43,33 MPa no C40. O consumo médio de cimento também aumentou progressivamente, de 323,59 kg/m³ no C25 para 404,13 kg/m³ no C40.

Em sentido contrário, a relação água/cimento apresentou redução com o aumento da classe de resistência, variando de aproximadamente 0,620 no C25 para 0,478 no C40. Esse comportamento é coerente com os resultados de resistência observados na base, uma vez que as classes de maior resistência apresentam, simultaneamente, maior consumo médio de cimento e menor relação água/cimento.

O abatimento médio também apresentou redução gradual, passando de aproximadamente 113,89 mm no C25 para 104,94 mm no C40. Já a densidade apresentou menor variação entre as classes, com médias entre aproximadamente 2362 e 2383 kg/m³. Dessa forma, entre as variáveis analisadas, as diferenças mais evidentes entre as classes estão associadas à resistência, ao consumo de cimento e à relação água/cimento.

5.5 Criando novas variáveis

####Crie uma variável chamada resistencia_relativa, representando a razão entre a resistência observada e uma resistência de referência associada à classe do concreto. Explique como você definiu a resistência de referência para cada classe.

Mostrar código
dados_corrigidos$resistencia_referencia <- ifelse(
  dados_corrigidos$tipo_concreto == "C25", 25,
  ifelse(
    dados_corrigidos$tipo_concreto == "C30", 30,
    ifelse(
      dados_corrigidos$tipo_concreto == "C35", 35,
      ifelse(
        dados_corrigidos$tipo_concreto == "C40", 40,
        NA
      )
    )
  )
)

dados_corrigidos$resistencia_relativa <-
  dados_corrigidos$resistencia_mpa /
  dados_corrigidos$resistencia_referencia

head(
  dados_corrigidos[
    c(
      "tipo_concreto",
      "resistencia_mpa",
      "resistencia_referencia",
      "resistencia_relativa"
    )
  ]
)
  tipo_concreto resistencia_mpa resistencia_referencia resistencia_relativa
1           C35            36.3                     35            1.0371429
2           C30            28.4                     30            0.9466667
3           C30            36.1                     30            1.2033333
4           C40            47.2                     40            1.1800000
5           C25            27.9                     25            1.1160000
6           C40            41.5                     40            1.0375000

Foi criada a variável resistencia_relativa, definida pela razão entre a resistência à compressão observada em cada corpo de prova e uma resistência de referência associada à respectiva classe do concreto.

Como referência, foram adotados os valores correspondentes à própria denominação das classes: 25 MPa para C25, 30 MPa para C30, 35 MPa para C35 e 40 MPa para C40. Dessa forma, valores de resistencia_relativa superiores a 1 indicam resistência observada acima da referência utilizada, enquanto valores inferiores a 1 indicam resistência abaixo dessa referência.

A variável foi criada com finalidade comparativa dentro da análise dos dados, permitindo avaliar a resistência observada em relação à classe de cada concreto.

5.5.1 Crie uma variável denominada classificacao, classificando os corpos de prova segundo um critério relacionado à resistência.

Você deverá definir os critérios utilizados e justificá-los tecnicamente.

Mostrar código
dados_corrigidos$classificacao <- ifelse(
  dados_corrigidos$resistencia_relativa < 1,
  "Abaixo da referência",
  ifelse(
    dados_corrigidos$resistencia_relativa < 1.10,
    "Atende à referência",
    "Acima da referência"
  )
)

table(dados_corrigidos$classificacao, useNA = "ifany")

Abaixo da referência  Acima da referência  Atende à referência 
                  24                   42                   33 
                <NA> 
                   1 

Foi criada a variável classificacao a partir da resistência relativa definida anteriormente. Os corpos de prova com resistência relativa inferior a 1 foram classificados como Abaixo da referência; aqueles com valores entre 1 e 1,10 foram classificados como Atende à referência; e os valores iguais ou superiores a 1,10 foram classificados como Acima da referência.

O critério foi adotado com finalidade descritiva, permitindo comparar a resistência observada de cada corpo de prova com a resistência de referência associada à sua classe. A faixa entre 1 e 1,10 foi utilizada para representar resultados próximos ou ligeiramente superiores à referência, enquanto valores acima desse limite indicam um desempenho mais elevado em relação ao valor adotado como referência.

Como resultado, foram classificados 24 corpos de prova abaixo da referência, 33 atendendo à referência e 42 acima da referência. Uma observação permaneceu sem classificação devido à ausência do valor de resistência à compressão.

5.5.2 Crie uma variável denominada 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.

A variável deverá assumir valores TRUE ou FALSE.

Mostrar código
media_tipo <- ave(
  dados_corrigidos$resistencia_mpa,
  dados_corrigidos$tipo_concreto,
  FUN = function(x) mean(x, na.rm = TRUE)
)

dados_corrigidos$acima_media <-
  dados_corrigidos$resistencia_mpa > media_tipo

table(dados_corrigidos$acima_media, useNA = "ifany")

FALSE  TRUE  <NA> 
   50    49     1 

Foi criada a variável acima_media, comparando a resistência de cada corpo de prova com a resistência média de sua respectiva classe de concreto. Para isso, utilizou-se a função ave(), que permitiu calcular a média da resistência para cada tipo de concreto e associá-la às respectivas observações.

A variável assume o valor TRUE quando a resistência do corpo de prova é superior à média de sua classe e FALSE quando é igual ou inferior. Como resultado, 49 corpos de prova apresentaram resistência acima da média de sua classe e 50 apresentaram resistência igual ou inferior. Uma observação permaneceu como NA, devido à ausência do valor de resistência à compressão.

5.6 Utilizando split(), lapply() e sapply()

5.6.1 Utilize split() para dividir a base de dados de acordo com a variável tipo_concreto.

Quantas observações existem em cada grupo?

Mostrar código
grupos_concreto <- split(
  dados_corrigidos,
  dados_corrigidos$tipo_concreto
)

sapply(grupos_concreto, nrow)
C25 C30 C35 C40 
 29  32  23  16 

A base de dados foi dividida de acordo com a variável tipo_concreto utilizando a função split(), resultando em quatro grupos correspondentes às classes C25, C30, C35 e C40.

Em seguida, a função sapply() foi utilizada em conjunto com nrow() para contar o número de observações em cada grupo. Foram identificadas 29 observações para C25, 32 para C30, 23 para C35 e 16 para C40, totalizando as 100 observações da base.

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

Mostrar código
lapply(
  grupos_concreto,
  function(x) mean(x$resistencia_mpa, na.rm = TRUE)
)
$C25
[1] 27.07241

$C30
[1] 32.07812

$C35
[1] 37.10455

$C40
[1] 43.33125

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

Foram obtidas resistências médias de aproximadamente 27,07 MPa para C25, 32,08 MPa para C30, 37,10 MPa para C35 e 43,33 MPa para C40.

O lapply() percorreu cada grupo da lista grupos_concreto e aplicou a função mean() à variável resistencia_mpa, retornando os resultados em formato de lista.

5.6.3 Repita a operação utilizando sapply().

Explique a diferença entre os resultados produzidos por lapply() e sapply().

Mostrar código
sapply(
  grupos_concreto,
  function(x) mean(x$resistencia_mpa, na.rm = TRUE)
)
     C25      C30      C35      C40 
27.07241 32.07812 37.10455 43.33125 

Utilizando sapply(), foram obtidas resistências médias de aproximadamente 27,07 MPa para C25, 32,08 MPa para C30, 37,10 MPa para C35 e 43,33 MPa para C40, reproduzindo os mesmos valores encontrados anteriormente com lapply().

A diferença entre as duas funções está no formato do resultado: o lapply() retorna os valores em formato de lista, enquanto o sapply() retorna os valores em um vetor numérico.

5.7 Utilizando apply()

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

Mostrar código
# Seleção das variáveis quantitativas relacionadas às propriedades do concreto
variaveis_quantitativas <- dados_corrigidos[
  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(
  variaveis_quantitativas,
  2,
  mean,
  na.rm = TRUE
)
      resistencia_mpa         cimento_kg_m3           relacao_a_c 
           33.5474747           357.6200000             0.5537374 
        abatimento_mm       densidade_kg_m3 absorção_agregado_pct 
          110.3333333          2373.1010101             1.7861616 

Foram selecionadas as variáveis quantitativas relacionadas às propriedades do concreto e utilizada a função apply() para calcular a média de cada uma delas.

Os resultados obtidos foram: 33,55 MPa para resistência à compressão, 357,62 kg/m³ para consumo de cimento, 0,554 para relação água/cimento, 110,33 mm para abatimento, 2373,10 kg/m³ para densidade e 1,79% para absorção do agregado.

5.7.2 Utilize apply() para obter, para cada observação, uma medida resumo envolvendo as variáveis quantitativas selecionadas.

Discuta:Essa medida resumo possui necessariamente uma interpretação física direta?

Mostrar código
# Cálculo de uma medida resumo para cada observação
resumo_observacao <- apply(
  variaveis_quantitativas,
  1,
  mean,
  na.rm = TRUE
)

# Visualização das primeiras observações
head(resumo_observacao)
[1] 479.5167 478.9650 484.9250 490.6067 487.9700 477.1217

Foi utilizada a função apply() para calcular, em cada observação, a média das variáveis quantitativas selecionadas, utilizando o argumento 1 para realizar o cálculo por linha.

Entretanto, essa média não possui significado físico e não é tecnicamente adequada para representar o concreto analisado. O cálculo combina grandezas completamente distintas, como resistência à compressão em MPa, consumo de cimento e densidade em kg/m³, abatimento em mm, absorção em porcentagem e relação água/cimento, que é adimensional.

Dessa forma, apesar de o R permitir matematicamente a aplicação da função mean() sobre esses valores, o resultado não representa nenhuma propriedade real do concreto. Somar e calcular a média entre resistência, abatimento, densidade e relação água/cimento mistura unidades, escalas e significados físicos diferentes, produzindo apenas um valor numérico sem interpretação técnica.

Portanto, nesta situação, o uso do apply() para gerar uma média por observação deve ser entendido apenas como um exercício de aplicação da função, e não como uma análise tecnicamente válida das propriedades do concreto.

5.8 Estruturas for e if

5.8.1 Utilizando for e if, percorra as 100 observações e identifique os corpos de prova cuja resistência esteja acima da resistência média de sua respectiva classe de concreto.

Mostrar código
medias_classes <- tapply(
  dados_corrigidos$resistencia_mpa,
  dados_corrigidos$tipo_concreto,
  mean,
  na.rm = TRUE
)

acima_media_for <- c()

for (i in 1:nrow(dados_corrigidos)) {
  
  if (!is.na(dados_corrigidos$resistencia_mpa[i])) {
    
    classe <- dados_corrigidos$tipo_concreto[i]
    
    if (dados_corrigidos$resistencia_mpa[i] > medias_classes[classe]) {
      
      acima_media_for <- c(
        acima_media_for,
        dados_corrigidos$id_corpo_prova[i]
      )
      
    }
  }
}

acima_media_for
 [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-025" "CP-027" "CP-028" "CP-030" "CP-031"
[17] "CP-035" "CP-037" "CP-039" "CP-040" "CP-041" "CP-042" "CP-048" "CP-050"
[25] "CP-051" "CP-052" "CP-055" "CP-056" "CP-057" "CP-060" "CP-061" "CP-062"
[33] "CP-065" "CP-066" "CP-070" "CP-073" "CP-074" "CP-075" "CP-078" "CP-081"
[41] "CP-082" "CP-083" "CP-085" "CP-087" "CP-089" "CP-090" "CP-091" "CP-095"
[49] "CP-099"
Mostrar código
length(acima_media_for)
[1] 49

Utilizando as estruturas for e if, as 100 observações da base foram percorridas individualmente. Para cada corpo de prova com valor de resistência disponível, sua resistência foi comparada com a resistência média da respectiva classe de concreto.

Ao final do processo, foram identificados 49 corpos de prova com resistência superior à média de sua classe, resultado compatível com o obtido anteriormente por meio de uma abordagem vetorizada.

A estrutura for foi utilizada para percorrer cada observação, enquanto os comandos if permitiram verificar inicialmente a existência de valor de resistência e, em seguida, comparar esse valor com a média correspondente à classe do concreto.

5.8.2 Repita a questão anterior utilizando uma abordagem vetorizada. Compare as duas soluções.Qual código você considera:mais simples; mais legível; mais eficiente?

Mostrar código
media_classe_vet <- ave(
  dados_corrigidos$resistencia_mpa,
  dados_corrigidos$tipo_concreto,
  FUN = function(x) mean(x, na.rm = TRUE)
)

acima_media_vet <- dados_corrigidos$resistencia_mpa > media_classe_vet

subset(
  dados_corrigidos,
  acima_media_vet == TRUE,
  select = c(id_corpo_prova, tipo_concreto, resistencia_mpa)
)
   id_corpo_prova tipo_concreto resistencia_mpa
3          CP-003           C30            36.1
4          CP-004           C40            47.2
5          CP-005           C25            27.9
8          CP-008           C30            38.7
14         CP-014           C35            39.4
16         CP-016           C25            28.7
17         CP-017           C35            38.4
18         CP-018           C30            34.7
22         CP-022           C40            45.2
23         CP-023           C30            35.5
24         CP-024           C40            44.7
25         CP-025           C25            27.2
27         CP-027           C30            39.4
28         CP-028           C30            33.6
30         CP-030           C35            44.6
31         CP-031           C35            40.7
35         CP-035           C35            41.1
37         CP-037           C30            36.6
39         CP-039           C40            44.9
40         CP-040           C25            29.4
41         CP-041           C25            31.4
42         CP-042           C30            32.3
48         CP-048           C30            32.1
50         CP-050           C30            32.7
51         CP-051           C30            33.1
52         CP-052           C25            31.6
55         CP-055           C25            28.2
56         CP-056           C35            37.9
57         CP-057           C30            33.5
60         CP-060           C25            29.3
61         CP-061           C25            29.3
62         CP-062           C25            29.5
65         CP-065           C30            35.6
66         CP-066           C35            41.6
70         CP-070           C25            29.8
73         CP-073           C40            46.5
74         CP-074           C25            27.8
75         CP-075           C35            41.8
78         CP-078           C40            46.9
81         CP-081           C40            47.5
82         CP-082           C40            43.4
83         CP-083           C25            28.0
85         CP-085           C30            38.3
87         CP-087           C25            27.8
89         CP-089           C25            28.3
90         CP-090           C30            33.1
91         CP-091           C35            39.6
95         CP-095           C25            30.3
99         CP-099           C25            31.1
Mostrar código
sum(acima_media_vet, na.rm = TRUE)
[1] 49

A abordagem vetorizada identificou os mesmos 49 corpos de prova com resistência superior à média de sua respectiva classe encontrados anteriormente com for e if.

Comparando as duas soluções, a abordagem vetorizada se mostrou mais simples e mais fácil para avaliar os dados, pois realiza a comparação diretamente entre os vetores, utilizando menos etapas e evitando a necessidade de percorrer individualmente cada observação. O código também fica mais curto e, neste caso, mais legível.

Em relação à eficiência, a abordagem vetorizada tende a ser mais eficiente por utilizar operações próprias do R sobre os vetores. Entretanto, para uma base pequena, com apenas 100 observações, essa diferença de desempenho é pouco relevante na prática. Assim, neste caso, sua principal vantagem está na simplicidade, legibilidade e facilidade de análise dos resultados.

5.9 Questões próximas da prática profissional

5.9.1 O engenheiro responsável afirma: “Os concretos utilizados no Bloco C apresentam desempenho superior aos utilizados nos demais blocos.”. Utilize a base de dados para verificar se os dados dão suporte a essa afirmação em termos descritivos.

Mostrar código
# 1. Resistência média por bloco
tapply(
  dados_corrigidos$resistencia_mpa,
  dados_corrigidos$obra,
  mean,
  na.rm = TRUE
)
 Bloco A  Bloco B  Bloco C  Bloco D 
33.18929 35.70000 32.37143 32.39333 
Mostrar código
# 2. Médias das propriedades do concreto por bloco
aggregate(
  cbind(
    resistencia_mpa,
    cimento_kg_m3,
    relacao_a_c,
    abatimento_mm,
    densidade_kg_m3,
    absorção_agregado_pct
  ) ~ obra,
  data = dados_corrigidos,
  FUN = mean,
  na.rm = TRUE
)
     obra resistencia_mpa cimento_kg_m3 relacao_a_c abatimento_mm
1 Bloco A        33.42963      361.4815   0.5537037      116.4815
2 Bloco B        35.67778      365.2963   0.5433333      108.3704
3 Bloco C        32.61852      351.2963   0.5625926      106.6667
4 Bloco D        33.35000      353.5000   0.5557143      105.2857
  densidade_kg_m3 absorção_agregado_pct
1        2376.519              1.753704
2        2375.407              1.759630
3        2366.778              1.774444
4        2372.786              1.875000
Mostrar código
# 3. Médias das propriedades por bloco e tipo de concreto
aggregate(
  cbind(
    resistencia_mpa,
    cimento_kg_m3,
    relacao_a_c,
    abatimento_mm,
    densidade_kg_m3,
    absorção_agregado_pct
  ) ~ obra + tipo_concreto,
  data = dados_corrigidos,
  FUN = mean,
  na.rm = TRUE
)
      obra tipo_concreto resistencia_mpa cimento_kg_m3 relacao_a_c
1  Bloco A           C25        28.27778      327.4444   0.6255556
2  Bloco B           C25        27.82500      321.5000   0.6250000
3  Bloco C           C25        27.03333      320.6667   0.6155556
4  Bloco D           C25        26.15000      315.5000   0.6050000
5  Bloco A           C30        30.52857      358.2857   0.5728571
6  Bloco B           C30        33.24444      351.4444   0.5700000
7  Bloco C           C30        32.01818      348.0909   0.5609091
8  Bloco D           C30        32.28000      349.2000   0.5720000
9  Bloco A           C35        35.78000      374.6000   0.4920000
10 Bloco B           C35        38.48000      380.4000   0.5160000
11 Bloco C           C35        35.10000      382.3333   0.4900000
12 Bloco D           C35        37.00000      380.0000   0.5333333
13 Bloco A           C40        42.58333      405.3333   0.4750000
14 Bloco B           C40        42.00000      402.5000   0.4700000
15 Bloco C           C40        44.97500      405.7500   0.5025000
16 Bloco D           C40        44.95000      400.5000   0.4500000
   abatimento_mm densidade_kg_m3 absorção_agregado_pct
1      123.55556        2373.556              1.880000
2      104.75000        2388.000              2.035000
3      106.88889        2368.778              1.873333
4      115.00000        2372.750              1.985000
5      117.57143        2404.714              1.440000
6      106.77778        2384.444              1.750000
7      111.36364        2370.545              1.602727
8      106.80000        2380.400              1.762000
9      110.80000        2352.000              2.064000
10     109.70000        2364.000              1.758000
11     100.33333        2357.333              1.770000
12      99.33333        2385.667              1.880000
13     109.33333        2368.500              1.671667
14     112.25000        2371.000              1.510000
15      98.00000        2359.000              2.027500
16      91.00000        2334.500              1.930000

A análise das médias gerais mostra que o Bloco C não apresenta desempenho superior de forma evidente. Sua resistência média foi de aproximadamente 32,62 MPa, enquanto o Bloco B apresentou 35,68 MPa, maior valor entre os blocos. O Bloco C, entretanto, apresentou o menor consumo médio de cimento (351,30 kg/m³). Para as demais variáveis, como relação água/cimento, abatimento, densidade e absorção, os resultados não indicam uma superioridade clara do Bloco C.

Como os blocos possuem diferentes classes de concreto, também foi realizada uma comparação separando C25, C30, C35 e C40. No C25, o Bloco C apresentou resistência média de 27,03 MPa, inferior aos blocos A e B, embora tenha apresentado menor consumo de cimento e menor relação água/cimento que esses dois blocos. No C30, o Bloco C apresentou 32,02 MPa, valor próximo aos melhores resultados, associado ao menor consumo de cimento (348,09 kg/m³) e à menor relação água/cimento (0,561) entre os blocos, indicando um resultado interessante nessa classe.

Para o C35, entretanto, o Bloco C apresentou a menor resistência média (35,10 MPa) e, simultaneamente, o maior consumo médio de cimento, não indicando desempenho superior nessa classe. Já no C40, o Bloco C apresentou a maior resistência média (44,98 MPa), praticamente igual ao Bloco D (44,95 MPa), embora também tenha apresentado o maior consumo médio de cimento.

Portanto, os dados mostram evidências pontuais de bom desempenho do Bloco C, principalmente nas classes C30 e C40, mas não sustentam uma superioridade geral em relação aos demais blocos. O desempenho varia conforme a classe e a variável analisada. Além disso, variáveis como abatimento, densidade e absorção não devem ser interpretadas simplesmente considerando valores maiores ou menores como melhores, pois dependem de critérios específicos de projeto, dosagem e controle tecnológico.

5.9.2 Outro engenheiro afirma: “Quanto maior o consumo de cimento, maior tende a ser a resistência do concreto”. Utilize a base para investigar essa afirmação. Quais variáveis devem ser analisadas conjuntamente?

Mostrar código
# Correlação entre consumo de cimento e resistência para toda a base
cor(
  dados_corrigidos$cimento_kg_m3,
  dados_corrigidos$resistencia_mpa,
  use = "complete.obs"
)
[1] 0.7803126
Mostrar código
# Correlação entre consumo de cimento e resistência por classe
by(
  dados_corrigidos,
  dados_corrigidos$tipo_concreto,
  function(x)
    cor(
      x$cimento_kg_m3,
      x$resistencia_mpa,
      use = "complete.obs"
    )
)
dados_corrigidos$tipo_concreto: C25
[1] 0.2796109
------------------------------------------------------------ 
dados_corrigidos$tipo_concreto: C30
[1] -0.1686683
------------------------------------------------------------ 
dados_corrigidos$tipo_concreto: C35
[1] -0.2438098
------------------------------------------------------------ 
dados_corrigidos$tipo_concreto: C40
[1] -0.03717286

Para investigar a afirmação, foram analisadas conjuntamente as variáveis consumo de cimento (cimento_kg_m3) e resistência à compressão (resistencia_mpa).

Considerando inicialmente toda a base, foi obtido um coeficiente de correlação de aproximadamente 0,78. Por ser positivo e relativamente próximo de 1, esse valor indica uma associação linear positiva relativamente forte: de forma geral, maiores consumos de cimento estão associados a maiores valores de resistência. Da mesma forma, menores consumos tendem a estar associados a menores resistências.

Entretanto, ao realizar a análise separadamente para cada classe de concreto, foram obtidas correlações de 0,28 para C25, -0,17 para C30, -0,24 para C35 e -0,04 para C40. Para o C25, o valor positivo de 0,28 indica uma tendência de aumento da resistência com o aumento do consumo de cimento, porém essa associação é fraca. Já para C30 e C35, os valores negativos indicam uma tendência inversa, ou seja, dentro dessas classes, maiores consumos de cimento estão associados a menores resistências, embora as correlações sejam fracas. No C40, o valor de -0,04 é muito próximo de zero, indicando praticamente ausência de associação linear entre as duas variáveis.

Dessa forma, os dados não permitem sustentar diretamente a afirmação de que simplesmente aumentar o consumo de cimento resulta em maior resistência. A forte correlação positiva observada na base completa parece estar relacionada principalmente às diferenças entre as classes de concreto, uma vez que concretos de classes superiores apresentam simultaneamente maiores consumos médios de cimento e maiores resistências. Quando cada classe é analisada separadamente, essa relação deixa de ser forte e consistente.

Portanto, a resistência não deve ser interpretada apenas em função da quantidade de cimento, mas considerando o conjunto da dosagem e os demais fatores que influenciam o comportamento do concreto.

5.9.3 Investigue a relação entre: relação água/cimento; resistência à compressão. Os dados apresentam algum padrão que mereça investigação?

Apresente sua análise e interprete os resultados.

Mostrar código
# Correlação entre relação água/cimento e resistência para toda a base
cor(
  dados_corrigidos$relacao_a_c,
  dados_corrigidos$resistencia_mpa,
  use = "complete.obs"
)
[1] -0.7639042
Mostrar código
# Correlação entre relação água/cimento e resistência por classe
by(
  dados_corrigidos,
  dados_corrigidos$tipo_concreto,
  function(x)
    cor(
      x$relacao_a_c,
      x$resistencia_mpa,
      use = "complete.obs"
    )
)
dados_corrigidos$tipo_concreto: C25
[1] 0.1003564
------------------------------------------------------------ 
dados_corrigidos$tipo_concreto: C30
[1] -0.1693216
------------------------------------------------------------ 
dados_corrigidos$tipo_concreto: C35
[1] 0.11166
------------------------------------------------------------ 
dados_corrigidos$tipo_concreto: C40
[1] 0.08824408

Para investigar a relação entre a relação água/cimento e a resistência à compressão, inicialmente foi calculada a correlação considerando toda a base de dados. O coeficiente obtido foi de aproximadamente -0,76, indicando uma associação linear negativa relativamente forte. Assim, de forma geral, os dados mostram uma tendência de que maiores relações água/cimento estejam associadas a menores valores de resistência, e vice-versa. Esse padrão merece investigação por apresentar uma associação considerável entre as duas variáveis.

Entretanto, ao separar os dados por classe de concreto, foram obtidas correlações de 0,10 para C25, -0,17 para C30, 0,11 para C35 e 0,09 para C40. Todos esses valores estão próximos de zero, indicando que, dentro de cada classe, existe pouca associação linear entre relação água/cimento e resistência nos dados analisados.

Portanto, embora a base completa apresente uma correlação negativa relativamente forte (-0,76), essa tendência não permanece quando cada classe de concreto é analisada separadamente. Isso indica que as diferenças existentes entre as próprias classes podem estar influenciando fortemente a correlação observada na análise geral. Assim, o padrão negativo encontrado na base completa é relevante e merece investigação mais aprofundada, mas não deve ser interpretado isoladamente como uma relação direta aplicável dentro de todas as classes de concreto.

5.9.4 Compare a resistência média dos concretos com diferentes idades. O que acontece com a resistência à medida que aumenta a idade do corpo de prova?

Mostrar código
# Resistência média por idade
tapply(
  dados_corrigidos$resistencia_mpa,
  dados_corrigidos$idade_dias,
  mean,
  na.rm = TRUE
)
       7       14       28       56 
28.78125 34.74000 34.65439 33.11818 
Mostrar código
# Resistência média por tipo de concreto e idade
tapply(
  dados_corrigidos$resistencia_mpa,
  list(
    dados_corrigidos$tipo_concreto,
    dados_corrigidos$idade_dias
  ),
  mean,
  na.rm = TRUE
)
          7       14       28    56
C25 25.2600 23.65000 27.90556 27.30
C30 28.9625 30.86667 33.30000 33.88
C35 30.0000 35.98333 37.89167 42.85
C40 42.5000 41.32500 44.13636    NA

Considerando inicialmente todos os concretos em conjunto, as resistências médias foram de 28,78 MPa aos 7 dias, 34,74 MPa aos 14 dias, 34,65 MPa aos 28 dias e 33,12 MPa aos 56 dias. Dessa forma, a análise geral mostra um aumento expressivo entre 7 e 14 dias, mas não apresenta crescimento contínuo nas idades seguintes.

Entretanto, essa comparação mistura diferentes classes de concreto e, por isso, não é suficiente para avaliar adequadamente o efeito da idade. Quando as classes são analisadas separadamente, o comportamento fica mais claro. O C30 apresenta aumento da resistência média de 28,96 MPa aos 7 dias para 33,88 MPa aos 56 dias, enquanto o C35 aumenta de 30,00 MPa para 42,85 MPa no mesmo intervalo. Nessas duas classes, portanto, observa-se uma tendência clara de aumento da resistência com a idade.

Para o C25, os resultados apresentam maior oscilação: 25,26 MPa aos 7 dias, 23,65 MPa aos 14 dias, 27,91 MPa aos 28 dias e 27,30 MPa aos 56 dias. No C40, também não ocorre crescimento contínuo entre as idades disponíveis, e não existem observações aos 56 dias.

Portanto, a base apresenta evidências de aumento da resistência com a idade principalmente para as classes C30 e C35, mas esse comportamento não é uniforme para todas as classes. A análise separada por tipo de concreto é mais adequada do que a comparação das médias gerais, pois evita que diferenças na distribuição das classes em cada idade distorçam a interpretação. Além disso, como os dados representam diferentes corpos de prova, e não necessariamente o acompanhamento do mesmo concreto ao longo do tempo, os resultados devem ser interpretados como uma tendência descritiva da base.

5.9.5 O controle tecnológico da empresa precisa produzir um relatório para o engenheiro responsável. Quais cinco informações estatísticas você considera mais importantes para apresentar? Justifique a escolha de cada uma.

Mostrar código
# 1. Resistência média por classe de concreto
tapply(
  dados_corrigidos$resistencia_mpa,
  dados_corrigidos$tipo_concreto,
  mean,
  na.rm = TRUE
)
     C25      C30      C35      C40 
27.07241 32.07812 37.10455 43.33125 
Mostrar código
# 2. Dispersão, mínimo e máximo da resistência por classe
by(
  dados_corrigidos$resistencia_mpa,
  dados_corrigidos$tipo_concreto,
  function(x) c(
    media = mean(x, na.rm = TRUE),
    desvio_padrao = sd(x, na.rm = TRUE),
    minimo = min(x, na.rm = TRUE),
    maximo = max(x, na.rm = TRUE)
  )
)
dados_corrigidos$tipo_concreto: C25
        media desvio_padrao        minimo        maximo 
    27.072414      3.067095     19.000000     31.600000 
------------------------------------------------------------ 
dados_corrigidos$tipo_concreto: C30
        media desvio_padrao        minimo        maximo 
    32.078125      3.565763     24.500000     39.400000 
------------------------------------------------------------ 
dados_corrigidos$tipo_concreto: C35
        media desvio_padrao        minimo        maximo 
    37.104545      3.683616     29.900000     44.600000 
------------------------------------------------------------ 
dados_corrigidos$tipo_concreto: C40
        media desvio_padrao        minimo        maximo 
    43.331250      3.081064     37.300000     47.500000 
Mostrar código
# 3. Resistência média por idade e classe
tapply(
  dados_corrigidos$resistencia_mpa,
  list(
    dados_corrigidos$tipo_concreto,
    dados_corrigidos$idade_dias
  ),
  mean,
  na.rm = TRUE
)
          7       14       28    56
C25 25.2600 23.65000 27.90556 27.30
C30 28.9625 30.86667 33.30000 33.88
C35 30.0000 35.98333 37.89167 42.85
C40 42.5000 41.32500 44.13636    NA
Mostrar código
# 4. Desempenho dos concretos entre os blocos

# Resistência média por bloco
tapply(
  dados_corrigidos$resistencia_mpa,
  dados_corrigidos$obra,
  mean,
  na.rm = TRUE
)
 Bloco A  Bloco B  Bloco C  Bloco D 
33.18929 35.70000 32.37143 32.39333 
Mostrar código
# Médias das propriedades por bloco
aggregate(
  cbind(
    resistencia_mpa,
    cimento_kg_m3,
    relacao_a_c,
    abatimento_mm,
    densidade_kg_m3,
    absorção_agregado_pct
  ) ~ obra,
  data = dados_corrigidos,
  FUN = mean,
  na.rm = TRUE
)
     obra resistencia_mpa cimento_kg_m3 relacao_a_c abatimento_mm
1 Bloco A        33.42963      361.4815   0.5537037      116.4815
2 Bloco B        35.67778      365.2963   0.5433333      108.3704
3 Bloco C        32.61852      351.2963   0.5625926      106.6667
4 Bloco D        33.35000      353.5000   0.5557143      105.2857
  densidade_kg_m3 absorção_agregado_pct
1        2376.519              1.753704
2        2375.407              1.759630
3        2366.778              1.774444
4        2372.786              1.875000
Mostrar código
# Médias das propriedades por bloco e tipo de concreto
aggregate(
  cbind(
    resistencia_mpa,
    cimento_kg_m3,
    relacao_a_c,
    abatimento_mm,
    densidade_kg_m3,
    absorção_agregado_pct
  ) ~ obra + tipo_concreto,
  data = dados_corrigidos,
  FUN = mean,
  na.rm = TRUE
)
      obra tipo_concreto resistencia_mpa cimento_kg_m3 relacao_a_c
1  Bloco A           C25        28.27778      327.4444   0.6255556
2  Bloco B           C25        27.82500      321.5000   0.6250000
3  Bloco C           C25        27.03333      320.6667   0.6155556
4  Bloco D           C25        26.15000      315.5000   0.6050000
5  Bloco A           C30        30.52857      358.2857   0.5728571
6  Bloco B           C30        33.24444      351.4444   0.5700000
7  Bloco C           C30        32.01818      348.0909   0.5609091
8  Bloco D           C30        32.28000      349.2000   0.5720000
9  Bloco A           C35        35.78000      374.6000   0.4920000
10 Bloco B           C35        38.48000      380.4000   0.5160000
11 Bloco C           C35        35.10000      382.3333   0.4900000
12 Bloco D           C35        37.00000      380.0000   0.5333333
13 Bloco A           C40        42.58333      405.3333   0.4750000
14 Bloco B           C40        42.00000      402.5000   0.4700000
15 Bloco C           C40        44.97500      405.7500   0.5025000
16 Bloco D           C40        44.95000      400.5000   0.4500000
   abatimento_mm densidade_kg_m3 absorção_agregado_pct
1      123.55556        2373.556              1.880000
2      104.75000        2388.000              2.035000
3      106.88889        2368.778              1.873333
4      115.00000        2372.750              1.985000
5      117.57143        2404.714              1.440000
6      106.77778        2384.444              1.750000
7      111.36364        2370.545              1.602727
8      106.80000        2380.400              1.762000
9      110.80000        2352.000              2.064000
10     109.70000        2364.000              1.758000
11     100.33333        2357.333              1.770000
12      99.33333        2385.667              1.880000
13     109.33333        2368.500              1.671667
14     112.25000        2371.000              1.510000
15      98.00000        2359.000              2.027500
16      91.00000        2334.500              1.930000
Mostrar código
# 5. Relação da resistência com parâmetros de dosagem
cor(
  dados_corrigidos[
    c(
      "resistencia_mpa",
      "cimento_kg_m3",
      "relacao_a_c"
    )
  ],
  use = "complete.obs"
)
                resistencia_mpa cimento_kg_m3 relacao_a_c
resistencia_mpa       1.0000000     0.7765170  -0.7639042
cimento_kg_m3         0.7765170     1.0000000  -0.7970658
relacao_a_c          -0.7639042    -0.7970658   1.0000000

Considerando as análises realizadas, as cinco informações estatísticas que considero mais importantes para um relatório de controle tecnológico são:

1. Resistência média por classe de concreto. As médias foram de 27,07 MPa para C25, 32,08 MPa para C30, 37,10 MPa para C35 e 43,33 MPa para C40. Essa informação permite avaliar o comportamento médio de cada classe separadamente, evitando comparar diretamente concretos com diferentes resistências de referência.

2. Dispersão e valores extremos da resistência. Além da média, considero importante apresentar o desvio-padrão e os valores mínimo e máximo de cada classe. Os desvios-padrão ficaram entre aproximadamente 3,07 e 3,68 MPa, demonstrando que existe variabilidade dentro das próprias classes. Essa informação é importante porque uma média satisfatória pode esconder resultados individuais baixos ou uma elevada dispersão dos ensaios.

3. Resistência em função da idade, separada por classe. A comparação entre 7, 14, 28 e 56 dias permite avaliar como os resultados de resistência se comportam ao longo das diferentes idades. A separação por classe é fundamental, pois a análise conjunta pode produzir interpretações equivocadas. Na base analisada, C30 e C35 apresentaram uma tendência clara de aumento da resistência com a idade, enquanto C25 e C40 apresentaram maior oscilação.

4. Comparação do desempenho dos concretos entre os blocos. Para essa avaliação, considero importante utilizar três níveis de análise: inicialmente, comparar a resistência média dos blocos; em seguida, analisar conjuntamente outras propriedades, como consumo de cimento, relação água/cimento, abatimento, densidade e absorção; e, por fim, repetir a análise separando também as classes de concreto. Essa abordagem evita definir desempenho apenas pela resistência média geral e reduz a influência das diferentes proporções de C25, C30, C35 e C40 existentes em cada bloco. Na análise realizada, por exemplo, o Bloco C apresentou resultados interessantes em determinadas classes e propriedades, mas não apresentou superioridade geral e consistente em relação aos demais blocos.

5. Relação entre resistência e parâmetros de dosagem. A análise conjunta da resistência, consumo de cimento e relação água/cimento permite investigar possíveis associações entre a dosagem e o desempenho mecânico. Na base completa, a resistência apresentou correlação positiva de aproximadamente 0,78 com o consumo de cimento e correlação negativa de aproximadamente -0,76 com a relação água/cimento. Essas informações são relevantes para identificar padrões nos dados, mas devem ser interpretadas com cautela, pois as análises anteriores mostraram que essas relações se alteram quando as diferentes classes de concreto são consideradas separadamente.

Essas cinco informações permitem que o relatório vá além da simples apresentação de médias, reunindo informações sobre desempenho, variabilidade, evolução com a idade, diferenças entre locais da obra e relações entre parâmetros de dosagem, fornecendo uma visão mais completa dos dados para auxiliar a tomada de decisão do engenheiro responsável.

6 Desafio final — O engenheiro responsável pelos dados

Você recebeu uma planilha produzida por diferentes profissionais da empresa e não sabe previamente quais erros foram cometidos durante a coleta e a digitação.

Desenvolva um script em R capaz de:

realizar uma inspeção inicial da base; identificar possíveis problemas; verificar valores ausentes; identificar inconsistências nas variáveis; produzir uma versão limpa dos dados; gerar estatísticas descritivas relevantes; criar pelo menos duas variáveis derivadas; produzir informações que possam auxiliar o engenheiro responsável pela obra. O script deverá ser organizado de forma que outro engenheiro consiga compreender as etapas realizadas.

Foi desenvolvido um script genérico para realizar a inspeção, limpeza e análise inicial de bases de dados sem conhecimento prévio dos possíveis erros existentes. Inicialmente, o código preserva a base original e verifica sua estrutura, os tipos das variáveis, os valores ausentes e a existência de registros duplicados.

Na etapa de processamento, são realizadas automaticamente apenas padronizações que não dependem de interpretação técnica, como a remoção de espaços excedentes e a transformação de campos vazios em NA. O script também identifica colunas de texto com predominância de valores numéricos e realiza sua conversão segundo o critério estabelecido. Valores que não podem ser convertidos são mantidos como pendências para avaliação posterior, evitando a atribuição de valores por suposição.

Além disso, são verificadas possíveis inconsistências entre categorias e identificados valores estatisticamente atípicos por meio do intervalo interquartil. Esses valores são apenas sinalizados, pois um outlier estatístico não representa necessariamente um erro e sua avaliação depende do contexto da variável. Também foram criadas as variáveis n_ausentes_linha e registro_completo, permitindo avaliar a qualidade de preenchimento de cada observação.

Na aplicação à base fornecida, o script identificou 7 valores ausentes, nenhuma linha duplicada, problemas de conversão em 2 variáveis, possível inconsistência categórica em 1 variável e possíveis valores atípicos em 4 variáveis. Após o processamento, foram geradas estatísticas descritivas e correlações entre as variáveis quantitativas, fornecendo informações para uma análise inicial da base.

Dessa forma, o script diferencia as etapas que podem ser automatizadas daquelas que exigem julgamento técnico. As inconsistências cuja correção não pode ser determinada de maneira segura são identificadas e mantidas para avaliação posterior, reduzindo o risco de introduzir novos erros durante o processo de limpeza dos dados.

Mostrar código
# ============================================================
# DESAFIO FINAL
# SCRIPT GENÉRICO PARA INSPEÇÃO, LIMPEZA E ANÁLISE DE DADOS
# ============================================================


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

dados <- read.csv2(
  "base_processamento_dados_engenharia_civil.csv",
  stringsAsFactors = FALSE,
  check.names = FALSE
)

# Preserva integralmente a base recebida
dados_original <- dados

# Cria a base de trabalho
dados_limpos <- dados


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

cat("\n===== ESTRUTURA DA BASE =====\n")

===== ESTRUTURA DA BASE =====
Mostrar código
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           : 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        : chr  "111.0" "114.0" "106.0" "142.0" ...
 $ densidade_kg_m3      : chr  "2332.0" "2389.0" "2427.0" "2345.0" ...
 $ absorção_agregado_pct: chr  "2.3" "1.85" "1.89" "1.97" ...
Mostrar código
cat("\n===== RESUMO INICIAL =====\n")

===== RESUMO INICIAL =====
Mostrar código
summary(dados_limpos)
   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   Length   :100  
 N.unique : 84    N.unique : 68   N.unique : 25   N.unique : 57  
 N.blank  :  1    N.blank  :  0   N.blank  :  1   N.blank  :  1  
 Min.nchar:  0    Min.nchar:  3   Min.nchar:  0   Min.nchar:  0  
 Max.nchar:  4    Max.nchar:  4   Max.nchar:  4   Max.nchar:  6  
                                                                 
  densidade_kg_m3 absorção_agregado_pct
 Length   :100    Length   :100        
 N.unique : 65    N.unique : 82        
 N.blank  :  1    N.blank  :  1        
 Min.nchar:  0    Min.nchar:  0        
 Max.nchar:  6    Max.nchar:  4        
                                       
Mostrar código
cat("\n===== CLASSES DAS VARIÁVEIS =====\n")

===== CLASSES DAS VARIÁVEIS =====
Mostrar código
print(
  sapply(dados_limpos, 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"           "character"           "character" 
absorção_agregado_pct 
          "character" 
Mostrar código
# 3. CORREÇÕES AUTOMÁTICAS SEGURAS -----------------------------

# São feitas apenas alterações que não dependem
# do significado técnico das variáveis.

for (variavel in names(dados_limpos)) {

  if (is.character(dados_limpos[[variavel]])) {

    # Remove espaços no início e no final
    dados_limpos[[variavel]] <-
      trimws(dados_limpos[[variavel]])

    # Campos vazios passam a ser NA
    dados_limpos[[variavel]][
      dados_limpos[[variavel]] == ""
    ] <- NA
  }
}


# 4. VALORES AUSENTES ------------------------------------------

cat("\n===== VALORES AUSENTES POR VARIÁVEL =====\n")

===== VALORES AUSENTES POR VARIÁVEL =====
Mostrar código
faltantes <- sapply(
  dados_limpos,
  function(x) sum(is.na(x))
)

print(faltantes)
       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 
Mostrar código
# 5. LINHAS EXATAMENTE DUPLICADAS ------------------------------

duplicadas <- duplicated(dados_limpos) |
  duplicated(dados_limpos, fromLast = TRUE)

cat("\n===== POSSÍVEIS LINHAS DUPLICADAS =====\n")

===== POSSÍVEIS LINHAS DUPLICADAS =====
Mostrar código
if (any(duplicadas)) {

  print(
    dados_limpos[
      duplicadas,
      ,
      drop = FALSE
    ]
  )

} else {

  cat("Nenhuma linha exatamente duplicada encontrada.\n")
}
Nenhuma linha exatamente duplicada encontrada.
Mostrar código
# 6. IDENTIFICAÇÃO E CONVERSÃO DE COLUNAS NUMÉRICAS ------------

# Colunas de texto com pelo menos 90% dos valores
# convertíveis são interpretadas como candidatas numéricas.
#
# A conversão é realizada automaticamente segundo esse critério,
# enquanto os valores não convertíveis são preservados
# em uma lista de pendências para avaliação posterior.

candidatas_numericas <- data.frame(
  variavel = character(),
  proporcao_numerica = numeric(),
  stringsAsFactors = FALSE
)

problemas_conversao <- list()

for (variavel in names(dados_limpos)) {

  if (is.character(dados_limpos[[variavel]])) {

    original <- dados_limpos[[variavel]]

    preenchidos <- !is.na(original)

    if (sum(preenchidos) > 0) {

      # Uniformiza vírgula decimal para ponto
      # apenas para testar a conversão numérica
      padronizado <- gsub(
        ",",
        ".",
        original,
        fixed = TRUE
      )

      convertido <- suppressWarnings(
        as.numeric(padronizado)
      )

      proporcao_numerica <-
        sum(!is.na(convertido[preenchidos])) /
        sum(preenchidos)

      # Critério adotado:
      # pelo menos 90% dos valores preenchidos são numéricos
      if (proporcao_numerica >= 0.90) {

        candidatas_numericas <- rbind(
          candidatas_numericas,
          data.frame(
            variavel = variavel,
            proporcao_numerica = proporcao_numerica
          )
        )

        # Identifica valores que impediram a conversão
        problema <- preenchidos &
          is.na(convertido)

        if (any(problema)) {

          problemas_conversao[[variavel]] <-
            data.frame(
              linha = which(problema),
              valor_original = original[problema],
              stringsAsFactors = FALSE
            )
        }

        # Converte a coluna
        dados_limpos[[variavel]] <- convertido
      }
    }
  }
}


cat("\n===== COLUNAS CONVERTIDAS PARA NUMÉRICO =====\n")

===== COLUNAS CONVERTIDAS PARA NUMÉRICO =====
Mostrar código
print(candidatas_numericas)
               variavel proporcao_numerica
1       resistencia_mpa           0.989899
2         cimento_kg_m3           0.990000
3           relacao_a_c           1.000000
4         abatimento_mm           1.000000
5       densidade_kg_m3           1.000000
6 absorção_agregado_pct           1.000000
Mostrar código
cat("\n===== VALORES NÃO CONVERTÍVEIS =====\n")

===== VALORES NÃO CONVERTÍVEIS =====
Mostrar código
if (length(problemas_conversao) > 0) {

  print(problemas_conversao)

} else {

  cat("Nenhum problema de conversão encontrado.\n")
}
$resistencia_mpa
  linha valor_original
1    19           3O,4

$cimento_kg_m3
  linha valor_original
1    64           390O
Mostrar código
# 7. POSSÍVEIS INCONSISTÊNCIAS NAS CATEGORIAS ------------------

# Procura categorias que diferem apenas por letras
# maiúsculas/minúsculas.
#
# Exemplo: "ABC" e "abc".
#
# O script apenas sinaliza, pois não é possível saber
# se representam a mesma categoria sem contexto.

inconsistencias_categorias <- list()

for (variavel in names(dados_limpos)) {

  if (is.character(dados_limpos[[variavel]])) {

    valores <- unique(
      dados_limpos[[variavel]]
    )

    valores <- valores[
      !is.na(valores)
    ]

    if (length(valores) > 1) {

      grupos <- split(
        valores,
        tolower(valores)
      )

      grupos_problema <- grupos[
        sapply(
          grupos,
          length
        ) > 1
      ]

      if (length(grupos_problema) > 0) {

        inconsistencias_categorias[[variavel]] <-
          grupos_problema
      }
    }
  }
}


cat("\n===== POSSÍVEIS CATEGORIAS INCONSISTENTES =====\n")

===== POSSÍVEIS CATEGORIAS INCONSISTENTES =====
Mostrar código
if (length(inconsistencias_categorias) > 0) {

  print(inconsistencias_categorias)

} else {

  cat("Nenhuma inconsistência desse tipo encontrada.\n")
}
$tipo_concreto
$tipo_concreto$c30
[1] "C30" "c30"
Mostrar código
# 8. RESUMO DAS VARIÁVEIS QUALITATIVAS ------------------------

variaveis_qualitativas <- names(
  dados_limpos
)[
  sapply(
    dados_limpos,
    is.character
  )
]

cat("\n===== VARIÁVEIS QUALITATIVAS =====\n")

===== VARIÁVEIS QUALITATIVAS =====
Mostrar código
print(variaveis_qualitativas)
[1] "id_corpo_prova" "obra"           "tipo_concreto" 
Mostrar código
# Frequências são apresentadas apenas quando
# o número de categorias é relativamente pequeno.
# Isso evita imprimir grandes listas de identificadores.

for (variavel in variaveis_qualitativas) {

  numero_categorias <- length(
    unique(
      dados_limpos[[variavel]][
        !is.na(dados_limpos[[variavel]])
      ]
    )
  )

  if (numero_categorias <= 20) {

    cat(
      "\nFrequências da variável:",
      variavel,
      "\n"
    )

    print(
      table(
        dados_limpos[[variavel]],
        useNA = "ifany"
      )
    )
  }
}

Frequências da variável: obra 

Bloco A Bloco B Bloco C Bloco D 
     28      29      28      15 

Frequências da variável: tipo_concreto 

C25 c30 C30 C35 C40 
 29   1  31  23  16 
Mostrar código
# 9. IDENTIFICAÇÃO DE POSSÍVEIS OUTLIERS -----------------------

# Utiliza o critério do intervalo interquartil (IQR).
#
# IMPORTANTE:
# um outlier estatístico não é automaticamente um erro.
# O valor é apenas sinalizado para avaliação posterior.

variaveis_numericas <- names(
  dados_limpos
)[
  sapply(
    dados_limpos,
    is.numeric
  )
]

possiveis_outliers <- list()

for (variavel in variaveis_numericas) {

  x <- dados_limpos[[variavel]]

  x_valido <- x[
    !is.na(x)
  ]

  if (length(x_valido) > 3) {

    Q1 <- quantile(
      x_valido,
      0.25
    )

    Q3 <- quantile(
      x_valido,
      0.75
    )

    intervalo <- IQR(
      x_valido
    )

    limite_inferior <-
      Q1 - 1.5 * intervalo

    limite_superior <-
      Q3 + 1.5 * intervalo

    problema <-
      !is.na(x) &
      (
        x < limite_inferior |
        x > limite_superior
      )

    if (any(problema)) {

      possiveis_outliers[[variavel]] <-
        data.frame(
          linha = which(problema),
          valor = x[problema]
        )
    }
  }
}


cat("\n===== POSSÍVEIS VALORES ATÍPICOS =====\n")

===== POSSÍVEIS VALORES ATÍPICOS =====
Mostrar código
if (length(possiveis_outliers) > 0) {

  print(possiveis_outliers)

} else {

  cat("Nenhum possível valor atípico identificado.\n")
}
$idade_dias
   linha valor
1      3    56
2      7    56
3     30    56
4     35    56
5     37    56
6     42    56
7     57    56
8     76    56
9     85   280
10    87    56
11    99    56
12   100    56

$abatimento_mm
  linha valor
1    16   175
2    32  1250
3    75    64

$densidade_kg_m3
  linha valor
1    21  2451
2    53   238
3    68  2460
4    90  2464

$absorção_agregado_pct
  linha valor
1    72  18.4
Mostrar código
# 10. VARIÁVEIS DERIVADAS DE QUALIDADE ------------------------

# Variáveis que podem ser utilizadas independentemente
# do tipo de base analisada.

dados_limpos$n_ausentes_linha <- apply(
  dados_limpos,
  1,
  function(x)
    sum(is.na(x))
)

dados_limpos$registro_completo <-
  dados_limpos$n_ausentes_linha == 0


cat("\n===== QUALIDADE DOS REGISTROS =====\n")

===== QUALIDADE DOS REGISTROS =====
Mostrar código
print(
  table(
    dados_limpos$registro_completo
  )
)

FALSE  TRUE 
    7    93 
Mostrar código
# 11. ESTATÍSTICAS DESCRITIVAS --------------------------------

variaveis_numericas <- names(
  dados_limpos
)[
  sapply(
    dados_limpos,
    is.numeric
  )
]

# Exclui a variável de controle criada pelo próprio script
variaveis_analise <- variaveis_numericas[
  variaveis_numericas != "n_ausentes_linha"
]


if (length(variaveis_analise) > 0) {

  cat("\n===== RESUMO DAS VARIÁVEIS NUMÉRICAS =====\n")

  print(
    summary(
      dados_limpos[
        variaveis_analise
      ]
    )
  )


  cat("\n===== MÉDIAS =====\n")

  print(
    sapply(
      dados_limpos[
        variaveis_analise
      ],
      mean,
      na.rm = TRUE
    )
  )


  cat("\n===== MEDIANAS =====\n")

  print(
    sapply(
      dados_limpos[
        variaveis_analise
      ],
      median,
      na.rm = TRUE
    )
  )


  cat("\n===== DESVIOS-PADRÃO =====\n")

  print(
    sapply(
      dados_limpos[
        variaveis_analise
      ],
      sd,
      na.rm = TRUE
    )
  )
}

===== RESUMO DAS VARIÁVEIS NUMÉRICAS =====
   idade_dias  resistencia_mpa cimento_kg_m3    relacao_a_c    
 Min.   :  7   Min.   :19.00   Min.   :295.0   Min.   :0.4300  
 1st Qu.: 14   1st Qu.:28.73   1st Qu.:339.0   1st Qu.:0.5100  
 Median : 28   Median :32.50   Median :353.0   Median :0.5600  
 Mean   : 28   Mean   :33.58   Mean   :357.3   Mean   :0.5537  
 3rd Qu.: 28   3rd Qu.:38.38   3rd Qu.:383.0   3rd Qu.:0.6000  
 Max.   :280   Max.   :47.50   Max.   :418.0   Max.   :0.6500  
               NAs    :2       NAs    :1       NAs    :1       
 abatimento_mm    densidade_kg_m3 absorção_agregado_pct
 Min.   :  64.0   Min.   : 238    Min.   : 0.800       
 1st Qu.:  99.5   1st Qu.:2348    1st Qu.: 1.475       
 Median : 110.0   Median :2374    Median : 1.850       
 Mean   : 121.7   Mean   :2351    Mean   : 1.953       
 3rd Qu.: 122.5   3rd Qu.:2388    3rd Qu.: 2.110       
 Max.   :1250.0   Max.   :2464    Max.   :18.400       
 NAs    :1        NAs    :1       NAs    :1            

===== MÉDIAS =====
           idade_dias       resistencia_mpa         cimento_kg_m3 
           28.0000000            33.5795918           357.2929293 
          relacao_a_c         abatimento_mm       densidade_kg_m3 
            0.5537374           121.6969697          2351.4646465 
absorção_agregado_pct 
            1.9534343 

===== MEDIANAS =====
           idade_dias       resistencia_mpa         cimento_kg_m3 
                28.00                 32.50                353.00 
          relacao_a_c         abatimento_mm       densidade_kg_m3 
                 0.56                110.00               2374.00 
absorção_agregado_pct 
                 1.85 

===== DESVIOS-PADRÃO =====
           idade_dias       resistencia_mpa         cimento_kg_m3 
          28.83600443            6.55646308           31.28971029 
          relacao_a_c         abatimento_mm       densidade_kg_m3 
           0.05816209          116.22361053          217.36578374 
absorção_agregado_pct 
           1.72870847 
Mostrar código
# 12. CORRELAÇÃO ENTRE VARIÁVEIS NUMÉRICAS --------------------

# Executa apenas se houver pelo menos
# duas variáveis numéricas disponíveis.

if (length(variaveis_analise) >= 2) {

  cat(
    "\n===== MATRIZ DE CORRELAÇÃO =====\n"
  )

  print(
    cor(
      dados_limpos[
        variaveis_analise
      ],
      use = "pairwise.complete.obs"
    )
  )
}

===== MATRIZ DE CORRELAÇÃO =====
                        idade_dias resistencia_mpa cimento_kg_m3 relacao_a_c
idade_dias             1.000000000      0.13055969  -0.038610925  0.12669618
resistencia_mpa        0.130559692      1.00000000   0.804694996 -0.76321066
cimento_kg_m3         -0.038610925      0.80469500   1.000000000 -0.80617981
relacao_a_c            0.126696184     -0.76321066  -0.806179811  1.00000000
abatimento_mm         -0.022385342      0.01944878   0.006808984 -0.02691138
densidade_kg_m3        0.009581706      0.07722880   0.010606137 -0.06637105
absorção_agregado_pct -0.045093065      0.05198571   0.134698589 -0.13106824
                      abatimento_mm densidade_kg_m3 absorção_agregado_pct
idade_dias             -0.022385342     0.009581706           -0.04509306
resistencia_mpa         0.019448780     0.077228801            0.05198571
cimento_kg_m3           0.006808984     0.010606137            0.13469859
relacao_a_c            -0.026911381    -0.066371053           -0.13106824
abatimento_mm           1.000000000     0.028287314            0.00797926
densidade_kg_m3         0.028287314     1.000000000            0.03168116
absorção_agregado_pct   0.007979260     0.031681156            1.00000000
Mostrar código
# 13. VERIFICAÇÃO FINAL ---------------------------------------

cat("\n===== ESTRUTURA FINAL =====\n")

===== ESTRUTURA FINAL =====
Mostrar código
str(dados_limpos)
'data.frame':   100 obs. of  12 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      : 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 ...
 $ n_ausentes_linha     : int  0 0 0 0 0 0 0 0 0 0 ...
 $ registro_completo    : logi  TRUE TRUE TRUE TRUE TRUE TRUE ...
Mostrar código
cat("\n===== RESUMO FINAL =====\n")

===== RESUMO FINAL =====
Mostrar código
summary(dados_limpos)
   id_corpo_prova        obra       tipo_concreto   idade_dias  resistencia_mpa
 Length   :100    Length   :100   Length   :100   Min.   :  7   Min.   :19.00  
 N.unique :100    N.unique :  4   N.unique :  5   1st Qu.: 14   1st Qu.:28.73  
 N.blank  :  0    N.blank  :  0   N.blank  :  0   Median : 28   Median :32.50  
 Min.nchar:  6    Min.nchar:  7   Min.nchar:  3   Mean   : 28   Mean   :33.58  
 Max.nchar:  6    Max.nchar:  7   Max.nchar:  3   3rd Qu.: 28   3rd Qu.:38.38  
                                                  Max.   :280   Max.   :47.50  
                                                                NAs    :2      
 cimento_kg_m3    relacao_a_c     abatimento_mm    densidade_kg_m3
 Min.   :295.0   Min.   :0.4300   Min.   :  64.0   Min.   : 238   
 1st Qu.:339.0   1st Qu.:0.5100   1st Qu.:  99.5   1st Qu.:2348   
 Median :353.0   Median :0.5600   Median : 110.0   Median :2374   
 Mean   :357.3   Mean   :0.5537   Mean   : 121.7   Mean   :2351   
 3rd Qu.:383.0   3rd Qu.:0.6000   3rd Qu.: 122.5   3rd Qu.:2388   
 Max.   :418.0   Max.   :0.6500   Max.   :1250.0   Max.   :2464   
 NAs    :1       NAs    :1        NAs    :1        NAs    :1      
 absorção_agregado_pct n_ausentes_linha registro_completo
 Min.   : 0.800        Min.   :0.00     Mode :logical    
 1st Qu.: 1.475        1st Qu.:0.00     FALSE:7          
 Median : 1.850        Median :0.00     TRUE :93         
 Mean   : 1.953        Mean   :0.07                      
 3rd Qu.: 2.110        3rd Qu.:0.00                      
 Max.   :18.400        Max.   :1.00                      
 NAs    :1                                               
Mostrar código
# 14. RESUMO DAS PENDÊNCIAS ----------------------------------

cat("\n===== RESUMO DAS PENDÊNCIAS =====\n")

===== RESUMO DAS PENDÊNCIAS =====
Mostrar código
cat(
  "\nValores ausentes:",
  sum(is.na(dados_limpos)),
  "\n"
)

Valores ausentes: 7 
Mostrar código
cat(
  "Linhas duplicadas:",
  sum(duplicadas),
  "\n"
)
Linhas duplicadas: 0 
Mostrar código
cat(
  "Variáveis com problemas de conversão:",
  length(problemas_conversao),
  "\n"
)
Variáveis com problemas de conversão: 2 
Mostrar código
cat(
  "Variáveis com possíveis inconsistências categóricas:",
  length(inconsistencias_categorias),
  "\n"
)
Variáveis com possíveis inconsistências categóricas: 1 
Mostrar código
cat(
  "Variáveis com possíveis outliers:",
  length(possiveis_outliers),
  "\n"
)
Variáveis com possíveis outliers: 4 
Mostrar código
cat(
  "\nProcessamento automático concluído.\n",
  "Padronizações inequívocas foram realizadas automaticamente.\n",
  "Colunas predominantemente numéricas foram convertidas segundo o critério adotado.\n",
  "As demais inconsistências foram sinalizadas para avaliação posterior.\n"
)

Processamento automático concluído.
 Padronizações inequívocas foram realizadas automaticamente.
 Colunas predominantemente numéricas foram convertidas segundo o critério adotado.
 As demais inconsistências foram sinalizadas para avaliação posterior.
Mostrar código
# ============================================================
# FIM DO PROCESSAMENTO
# ============================================================

7 Reflexão final

Depois de concluir a atividade, responda:

Por que o processamento e a limpeza dos dados são etapas fundamentais antes da aplicação de métodos estatísticos na Engenharia Civil?

Em seguida, descreva brevemente qual foi o principal problema encontrado na base e qual decisão você tomou para tratá-lo.

O processamento e a limpeza dos dados são etapas fundamentais antes da aplicação de métodos estatísticos, pois a presença de erros de digitação, valores ausentes, inconsistências de formato ou valores incompatíveis pode alterar os resultados e levar a interpretações equivocadas. Na Engenharia Civil, essa etapa se torna ainda mais importante porque as análises estatísticas podem subsidiar decisões técnicas. Portanto, antes de calcular médias, correlações ou realizar comparações, é necessário verificar a qualidade e a consistência dos dados utilizados.

Na base analisada, os principais erros encontrados envolveram duas situações: erros de digitação e formatação, como valores registrados de maneira incorreta ou categorias sem padronização; e valores numericamente válidos, mas potencialmente inconsistentes, que exigem uma análise técnica para determinar se representam um erro ou uma observação real. A decisão adotada foi corrigir automaticamente apenas os problemas cuja interpretação era segura e sinalizar os demais para avaliação posterior, evitando substituir dados por valores presumidos.

8 🧠 Considerações finais

O desenvolvimento deste relatório permitiu aplicar os principais recursos da linguagem R no processamento, organização e análise de dados relacionados à Engenharia Civil. A utilização de funções da linguagem base possibilitou realizar desde a inspeção e correção da base até o agrupamento das informações, cálculo de medidas estatísticas e investigação das relações entre diferentes variáveis.

A análise evidenciou a importância de avaliar criticamente os dados antes de interpretar os resultados estatísticos. Foram identificados valores ausentes, erros de digitação e formatação, inconsistências entre categorias e valores que exigiram avaliação técnica antes de qualquer correção. Também foi possível observar que resultados aparentemente claros podem apresentar interpretações diferentes quando as variáveis são analisadas de forma conjunta ou separadas por grupos. Um exemplo foi a relação entre consumo de cimento e resistência, que apresentou correlação positiva quando considerada toda a base, mas comportamento diferente quando analisada separadamente por classe de concreto.

As análises realizadas também mostraram que a aplicação de uma função estatística deve estar associada ao significado físico das variáveis. Nem todo cálculo matematicamente possível produz uma informação tecnicamente útil, como observado ao calcular uma medida resumo por observação envolvendo grandezas com unidades e significados distintos. Dessa forma, a interpretação dos resultados deve considerar não apenas o valor obtido, mas também o contexto técnico no qual os dados estão inseridos.

Por fim, o desenvolvimento de um script genérico de inspeção e limpeza demonstrou a possibilidade de automatizar parte do tratamento de bases desconhecidas, mantendo separadas as correções que podem ser realizadas de forma objetiva daquelas que dependem do julgamento do profissional. Assim, o uso do R mostrou-se uma ferramenta útil não apenas para a execução de cálculos estatísticos, mas também para a organização, verificação e análise crítica de dados que podem subsidiar decisões na Engenharia Civil.

9 📖 Referências

9.1 💬 Exemplo de como citar uma referência bibliográfica

Depois de inserido as informaçõe no arquivo referencias.bib, use:

Referências

BATISTA, B. D. O.; OLIVEIRA, D. A. B. J. R básico. 1. ed. Ouro Branco, MG: [s.n.], 2022. p. 321