Este relatório descreve o processamento de dados realizado para o Projeto Castanhão, com foco na construção de um modelo para análise da clorofila em função de variáveis ambientais. O objetivo principal foi consolidar dados de múltiplas planilhas Excel contendo informações sobre:
#### Projeto Castanhão - Paulo - Modelo Clorofila
# Data: 10/08/2025
# Autor: Carlos Antônio Zarzar
#-------------------------------------------------------------------------------
# Objetivo:
# Juntar os dados de clorofila, Nitrogênio total, Posforo total, Turbidez, profundidade, Precipitação
#-------------------------------------------------------------------------------
# Pacotes
library(readxl)
library(dplyr)
library(lubridate)
# Limpando área de trabalho
rm(list = ls())
Os dados foram importados de dois arquivos Excel principais: -
Dados Castanhão.xlsx
(contendo 4 planilhas diferentes) -
Precipitação.xlsx
# Importando dados
df_chl <- read_xlsx("Dados Castanhão.xlsx", sheet = "Clorofila a ")
df_nt <- read_xlsx("Dados Castanhão.xlsx", sheet = "Nitrogênio Total")
df_pt <- read_xlsx("Dados Castanhão.xlsx", sheet = "Fósforo Total")
df_turb <- read_xlsx("Dados Castanhão.xlsx", sheet = "Turbidez")
df_precip <- read_xlsx("Precipitação.xlsx", sheet = "Precipitação")
df_precip$Precipitação <- as.numeric(df_precip$Precipitação)
Observação: Foram detectados valores NA na conversão da coluna Precipitação.
Definiu-se um conjunto padrão de colunas para todos os data frames:
# Colunas desejadas
colunas_desejadas <- c("CAMPANHA","PONTO","PROF","DATA_COLETA","HORARIO","RESULTADO","DESCR_PONTO")
# Lista com os data frames originais
lista_df <- list(
df_chl = df_chl,
df_nt = df_nt,
df_pt = df_pt,
df_turb = df_turb
)
# Função para selecionar as colunas (mantém só as que existem no DF)
selecionar_colunas <- function(df) {
df[, intersect(colunas_desejadas, colnames(df)), drop = FALSE]
}
# Aplica a função a todos os data frames
lista_df <- lapply(lista_df, selecionar_colunas)
Para facilitar a identificação posterior, a coluna “RESULTADO” foi renomeada conforme o tipo de medição:
# Renomeando as Colunas RESULTADO para cada Data Frame
lista_df <- list(
chl = df_chl,
nt = df_nt,
pt = df_pt,
turb = df_turb
)
# Criar uma lista vazia para armazenar os data frames processados
lista_df_processada <- list()
# Loop sobre cada data frame da lista original
for (nome_df in names(lista_df)) {
# Extrai o data frame atual da lista
df_atual <- lista_df[[nome_df]]
# Seleciona somente as colunas que existem tanto na lista desejada quanto no data frame atual
colunas_presentes <- intersect(colunas_desejadas, names(df_atual))
df_selecionado <- df_atual[, colunas_presentes, drop = FALSE]
# Verifica se a coluna "RESULTADO" está presente para renomeá-la
if ("RESULTADO" %in% names(df_selecionado)) {
# Renomeia "RESULTADO" para o nome do data frame atual
names(df_selecionado)[names(df_selecionado) == "RESULTADO"] <- nome_df
}
# Salva o data frame processado na lista nova
lista_df_processada[[nome_df]] <- df_selecionado
}
# Reatribui os data frames processados para as variáveis originais
df_chl <- lista_df_processada$chl
df_nt <- lista_df_processada$nt
df_pt <- lista_df_processada$pt
df_turb <- lista_df_processada$turb
Resultado: Cada data frame agora possui colunas padronizadas com a variável de interesse renomeada apropriadamente (chl, nt, pt, turb).
# Análise comparação (match)
# Dados correspondente
dados_match <- merge(
df_chl,
df_nt,
by = c("CAMPANHA", "PONTO", "PROF", "DATA_COLETA")
)
# print(dados_match)
dim(dados_match) # Resultado: [1] 330 10
## [1] 330 10
Resultado: Foram encontrados 330 registros com correspondência perfeita entre os dados de clorofila e nitrogênio total.
# Função para detectar duplicatas
checar_duplicatas <- function(df, nome_df) {
df %>%
count(CAMPANHA, PONTO, PROF, DATA_COLETA) %>%
filter(n > 1) %>%
arrange(desc(n)) %>%
mutate(dataframe = nome_df)
}
# Aplicar a função a todos os data frames
duplicatas <- bind_rows(
lapply(names(lista_df), function(nome) {
checar_duplicatas(lista_df[[nome]], nome)
})
)
Resultado: Foram identificadas 78 chaves duplicadas, principalmente nos dados de clorofila, com alguns registros tendo até 4 repetições para a mesma combinação de campanha, ponto, profundidade e data.
# Lista com todos os data frames
lista_df <- list(df_chl, df_nt, df_pt, df_turb)
# Faz o full join de todos de uma vez
dados_full <- Reduce(function(x, y) {
full_join(x, y, by = c("CAMPANHA", "PONTO", "PROF", "DATA_COLETA"))
}, lista_df)
print(dados_full)
## # A tibble: 1,281 × 16
## CAMPANHA PONTO PROF DATA_COLETA HORARIO.x chl
## <chr> <chr> <dbl> <dttm> <dttm> <dbl>
## 1 fev/2013 CTN-20 0.3 2013-02-19 00:00:00 1899-12-31 10:30:00 6.41
## 2 fev/2013 CTN-18 0.3 2013-02-19 00:00:00 1899-12-31 15:00:00 2.67
## 3 fev/2013 CTN-10 0.3 2013-02-19 00:00:00 1899-12-31 11:10:00 1
## 4 fev/2013 CTN-05 0.3 2013-02-19 00:00:00 1899-12-31 11:30:00 1
## 5 fev/2013 CTN-01 0.3 2013-02-19 00:00:00 1899-12-31 12:00:00 1
## 6 mai/2013 CTN-20 0.3 2013-05-20 00:00:00 1899-12-31 10:55:00 7.5
## 7 mai/2013 CTN-18 0.3 2013-05-20 00:00:00 1899-12-31 13:30:00 7.8
## 8 mai/2013 CTN-10 0.3 2013-05-20 00:00:00 1899-12-31 12:40:00 10.4
## 9 mai/2013 CTN-05 0.3 2013-05-20 00:00:00 1899-12-31 12:20:00 8.58
## 10 mai/2013 CTN-01 0.3 2013-05-20 00:00:00 1899-12-31 13:00:00 11.2
## # ℹ 1,271 more rows
## # ℹ 10 more variables: DESCR_PONTO.x <chr>, HORARIO.y <dttm>, nt <dbl>,
## # DESCR_PONTO.y <chr>, HORARIO.x.x <dttm>, pt <dbl>, DESCR_PONTO.x.x <chr>,
## # HORARIO.y.y <dttm>, turb <dbl>, DESCR_PONTO.y.y <chr>
## [1] 1281 16
Observações importantes: - Foram detectadas relações muitos-para-muitos durante o join - O dataset consolidado possui 1.281 registros com 16 colunas
# Excluindo linhas que não têm dados de clorofila
num_NA <- table(is.na(dados_full$chl))
cat("Número de linhas excluídas:",num_NA["TRUE"]) # 690 linhas
## Número de linhas excluídas: 690
## [1] 591 16
# Remove linhas onde nt, pt e turb são todos NA ao mesmo tempo
df_limpo <- df[!(is.na(df$nt) & is.na(df$pt) & is.na(df$turb)), ]
num_NA <- table((is.na(df$nt) & is.na(df$pt) & is.na(df$turb)))
cat("Número de linhas excluídas:",num_NA["TRUE"]) # 1 linha
## Número de linhas excluídas: 1
## [1] 590 16
tam_linhas <- dim(df_limpo)[1]
nao_tem_turb <- table((is.na(df_limpo$turb)))
cat("Tamanho do conjunto de dados após processamento (df_limpo):",tam_linhas) # 590
## Tamanho do conjunto de dados após processamento (df_limpo): 590
## Excluindo linhas que não tem informação da Turbidez: 512
## Dimensão dos dados se excluir NA da Turbidez: 78
Problema Crítico: Apenas 78 registros (13,2%) possuem dados de turbidez, o que representa uma limitação significativa para a modelagem.
chl
: Clorofila-a (mg/L) - 100% dos registrosnt
: Nitrogênio Total (mg/L) - ~87% dos registrospt
: Fósforo Total (mg/L) - ~87% dos registrosturb
: Turbidez (NTU) - ~13% dos registrosPrecipitação
: mm/mês - 100% dos registros## CAMPANHA PONTO PROF DATA_COLETA HORARIO.x chl nt pt turb
## 1 fev/2013 CTN-20 0.3 2013-02-19 1899-12-31 10:30:00 6.41 0.03 0.01 3.52
## 2 fev/2013 CTN-18 0.3 2013-02-19 1899-12-31 15:00:00 2.67 0.03 0.01 NA
## 3 fev/2013 CTN-10 0.3 2013-02-19 1899-12-31 11:10:00 1.00 0.72 0.01 NA
## 4 fev/2013 CTN-05 0.3 2013-02-19 1899-12-31 11:30:00 1.00 0.03 0.01 NA
## 5 fev/2013 CTN-01 0.3 2013-02-19 1899-12-31 12:00:00 1.00 0.03 0.01 NA
## 6 mai/2013 CTN-20 0.3 2013-05-20 1899-12-31 10:55:00 7.50 0.03 0.02 5.19
## Precipitação DESCR_PONTO.x mes ano
## 1 66.9 CTN-20 2 2013
## 2 66.9 CTN-18 2 2013
## 3 66.9 CTN-10 2 2013
## 4 66.9 CTN-05 2 2013
## 5 66.9 CTN-01 2 2013
## 6 116.5 CTN-20 5 2013
# Dimensões finais do dataset
cat("Dimensões do dataset final:", dim(df_castanhao)[1], "observações e", dim(df_castanhao)[2], "variáveis\n")
## Dimensões do dataset final: 590 observações e 13 variáveis
# Resumo das variáveis numéricas
summary(df_castanhao[,c("chl", "nt", "pt", "turb", "Precipitação")])
## chl nt pt turb
## Min. : 1.00 Min. :0.020 Min. :0.01000 Min. : 0.600
## 1st Qu.: 9.37 1st Qu.:0.875 1st Qu.:0.05500 1st Qu.: 2.955
## Median : 15.93 Median :0.963 Median :0.08400 Median : 5.140
## Mean : 21.06 Mean :1.079 Mean :0.09408 Mean : 7.601
## 3rd Qu.: 27.84 3rd Qu.:1.150 3rd Qu.:0.09400 3rd Qu.: 9.500
## Max. :143.47 Max. :4.270 Max. :1.03000 Max. :36.700
## NA's :512
## Precipitação
## Min. : 0.00
## 1st Qu.: 3.80
## Median : 10.20
## Mean : 31.57
## 3rd Qu.: 43.90
## Max. :227.00
## NA's :147
Exemplo dos dados processados:
CAMPANHA PONTO PROF DATA_COLETA HORARIO.x chl nt pt turb Precipitação
1 fev/2013 CTN-20 0.3 2013-02-19 1899-12-31 10:30:00 6.41 0.03 0.01 3.52 66.9
2 fev/2013 CTN-18 0.3 2013-02-19 1899-12-31 15:00:00 2.67 0.03 0.01 NA 66.9
Dados de Turbidez Limitados: Apenas 13,2% dos registros possuem dados de turbidez, o que pode comprometer a capacidade de modelagem desta variável.
Horários Inconsistentes: Muitos registros apresentam horário como “00:00:00”, indicando possível inconsistência na coleta temporal.
Duplicatas: Foram identificadas chaves duplicadas que podem requerer tratamento adicional.
Interpolação de Turbidez: Considerar métodos de interpolação ou estimativa da turbidez com base em outras variáveis disponíveis (precipitação, clorofila, nutrientes).
Análise Temporal: Investigar mais profundamente as inconsistências nos horários de coleta.
Tratamento de Duplicatas: Definir critério para tratamento das observações duplicadas.
Dataset final: df_castanhao
com 590
observações e 13 variáveis, pronto para análise e modelagem
estatística.