Tutorial: Análise de Temperatura ERA5 para Favelas
Um Guia Passo a Passo para Buscar e Analisar Dados Climáticos com R
Published
November 25, 2025
Introdução
Este tutorial demonstra como buscar, processar e visualizar dados de temperatura do ERA5, a mais moderna reanálise climática global do ECMWF (Centro Europeu de Previsões Meteorológicas de Médio Prazo). Vamos cruzar esses dados com as coordenadas geográficas de favelas para extrair a temperatura em cada local, incluindo uma série histórica dos últimos 10 anos.
🎯 Objetivo
Extrair a temperatura do ar (a 2 metros de altura) para uma lista de favelas, usando suas latitudes e longitudes, e visualizar os resultados ao longo de uma série histórica de 10 anos (2016-2026).
🛠️ Ferramentas Utilizadas
Linguagem R: Uma linguagem poderosa para análise estatística e visualização de dados.
Pacote ecmwfr: Para conectar e baixar dados da API do Climate Data Store (CDS).
Pacote terra: Para manipular os dados climáticos em formato raster.
Pacotes tidyverse: Para manipulação e visualização de dados em geral.
Pacote jsonlite: Para exportar dados em formato JSON para sistemas web.
Passo 1: Preparação do Ambiente
O primeiro passo é garantir que todos os pacotes necessários estejam instalados e carregados no R.
1.1. Instalação dos Pacotes
O código abaixo verifica se os pacotes necessários já estão instalados e, caso contrário, os instala automaticamente. Execute este chunk apenas uma vez.
Mostrar/Ocultar Código
# Lista de pacotes necessáriospacotes_necessarios <-c("ecmwfr", # Interface para a API do CDS"tidyverse", # Manipulação e visualização de dados (inclui ggplot2, dplyr, etc.)"ncdf4", # Leitura de arquivos NetCDF (formato dos dados do ERA5)"terra", # Processamento de dados raster (geográficos)"sf", # Manipulação de dados espaciais vetoriais"viridis", # Paletas de cores para gráficos"jsonlite"# Exportação de dados em formato JSON)# Função para instalar pacotes apenas se não estiverem presentesinstalar_se_necessario <-function(pacotes) { novos_pacotes <- pacotes[!(pacotes %in%installed.packages()[, "Package"])]if (length(novos_pacotes)) {install.packages(novos_pacotes, dependencies =TRUE, repos ="https://cloud.r-project.org/") }}# Executa a instalaçãoinstalar_se_necessario(pacotes_necessarios)cat("Todos os pacotes necessários estão instalados!\n")
1.2. Carregamento dos Pacotes
Agora, vamos carregar os pacotes que usaremos ao longo do tutorial.
Mostrar/Ocultar Código
# Carrega os pacotes de forma silenciosasuppressPackageStartupMessages({library(ecmwfr)library(tidyverse)library(ncdf4)library(terra)library(sf)library(viridis)library(jsonlite)})cat("✓ Pacotes carregados com sucesso!\n")
✓ Pacotes carregados com sucesso!
Passo 2: Configuração da API do CDS
Para baixar dados do ERA5, você precisa de uma conta gratuita no Climate Data Store (CDS) e de uma chave de API.
Acesse seu perfil: Após o login, clique no seu nome no canto superior direito e vá para “Your profile”.
Copie sua chave: Na parte inferior da página, você encontrará sua API key. Ela se parece com isto: 12345:abcdef-1234-5678-90ab-cdef12345678.
2.2. Configurando a Chave no R
O pacote ecmwfr precisa saber sua chave. A função abaixo configura a chave para a sessão atual. Substitua SUA_API_KEY_AQUI pela sua chave real.
Mostrar/Ocultar Código
# Insira sua chave de API aquiminha_api_key <-"8d9e5944-896a-4584-a7ef-136ede4aa1d2"# Configura a chave para a sessão atual# A nova API usa a chave completa no campo 'user' e 'key'wf_set_key(user ="8d9e5944-896a-4584-a7ef-136ede4aa1d2", key ="8d9e5944-896a-4584-a7ef-136ede4aa1d2")cat("✓ Cliente CDS configurado com sucesso!\n")# IMPORTANTE: Aceite os termos de uso!# Antes de prosseguir, acesse o link abaixo, faça login e aceite os termos de uso do dataset.# Link: https://cds.climate.copernicus.eu/cdsapp#!/datasets/reanalysis-era5-single-levels
Aviso: Antes de baixar os dados, você precisa aceitar os termos de uso do dataset ERA5. Acesse o link do dataset, faça login, vá para a aba “Download data” e aceite os termos. Você só precisa fazer isso uma vez.
Passo 3: Carregar e Preparar os Dados das Favelas
Agora, vamos carregar o arquivo CSV com os dados das favelas e prepará-lo para a análise.
3.1. Carregando o Arquivo CSV
Vamos carregar o arquivo Favelas_Municipais.csv. Certifique-se de que este arquivo esteja no mesmo diretório do seu script R ou forneça o caminho completo.
Mostrar/Ocultar Código
# Caminho para o arquivo de dadosarquivo_favelas <-"Escolas_Municipais.csv"# Carrega os dadosdf_favelas <-read.csv(arquivo_favelas, fileEncoding ="UTF-8")# Remove o caractere BOM (Byte Order Mark) que às vezes aparece no inícionames(df_favelas)[1] <-gsub("^\uFEFF", "", names(df_favelas)[1])cat(sprintf("✓ Dados carregados: %d favelas\n", nrow(df_favelas)))
✓ Dados carregados: 12741 favelas
Mostrar/Ocultar Código
# Exibe as primeiras linhas e a estrutura dos dadoshead(df_favelas)
gid cd_fcu nm_fcu cd_uf
1 1 35503080069 Jardim Miliunas 35
2 2 42024040016 Rua Araranguá 42
3 3 33045570554 Tiqui 33
4 4 33045570104 Parque Nossa Senhora da Penha 33
5 5 35095020135 Núcleo Residencial Jardim das Andorinhas II 35
6 6 33033020044 Morro do Peixe Galo 33
nm_uf sigla_uf cd_mun nm_mun cod_prov latitude longitude
1 São Paulo SP 3550308 São Paulo 4500 -23.49953 -46.37127
2 Santa Catarina SC 4202404 Blumenau 8175 -26.93605 -49.05292
3 Rio de Janeiro RJ 3304557 Rio de Janeiro 9521 -22.88999 -43.48308
4 Rio de Janeiro RJ 3304557 Rio de Janeiro 7217 -22.87610 -43.21633
5 São Paulo SP 3509502 Campinas 6648 -22.91879 -47.01470
6 Rio de Janeiro RJ 3303302 Niterói 6070 -22.93630 -43.11104
3.2. Limpeza e Validação das Coordenadas
É uma boa prática limpar os dados, garantindo que não há coordenadas ausentes ou inválidas.
Mostrar/Ocultar Código
# Filtra favelas com coordenadas válidas para o Rio de Janeirodf_favelas_clean <- df_favelas %>%# Remove linhas onde latitude ou longitude são nulasfilter(!is.na(latitude) &!is.na(longitude)) %>%# Garante que as coordenadas são numéricasmutate(latitude =as.numeric(latitude), longitude =as.numeric(longitude)) # Filtra coordenadas que estão fora da área esperada para o RJ#filter(latitude >= -23.5 & latitude <= -22.5,# longitude >= -44.0 & longitude <= -43.0)cat(sprintf("✓ Pré-processamento concluído: %d favelas válidas restantes.\n", nrow(df_favelas_clean)))
Passo 4: Baixar os Dados de Temperatura do ERA5 (Série Histórica)
Com as coordenadas limpas, podemos definir a área de interesse e baixar os dados de temperatura para os últimos 10 anos.
4.1. Definindo a Área de Download (Bounding Box)
Para otimizar o download, criamos uma “caixa” (bounding box) um pouco maior que a área coberta por todas as favelas.
Mostrar/Ocultar Código
# Adiciona uma margem de 0.1 graus (~11 km) para garantir a coberturalat_min <-min(df_favelas_clean$latitude) -0.1lat_max <-max(df_favelas_clean$latitude) +0.1lon_min <-min(df_favelas_clean$longitude) -0.1lon_max <-max(df_favelas_clean$longitude) +0.1cat("Área de interesse para download (Bounding Box):\n")
4.2. Criando a Requisição e Baixando os Dados (Últimos 10 Anos)
Agora, montamos a requisição para a API do CDS. Vamos pedir a temperatura (2m_temperature) para cada mês dos últimos 10 anos (2016-2026).
Mostrar/Ocultar Código
# Define os anos para a série histórica (últimos 10 anos)anos <-2016:2025# Função para fazer download dos dados para cada anobaixar_dados_serie_historica <-function(anos, lat_max, lon_min, lat_min, lon_max, minha_api_key) { lista_arquivos <-list()for (ano in anos) {cat(sprintf("\n📥 Baixando dados para o ano %d...\n", ano))# Define os parâmetros da requisição request <-list(dataset_short_name ="reanalysis-era5-single-levels-monthly-means",product_type ="monthly_averaged_reanalysis",variable ="2m_temperature",year =as.character(ano),month =c("01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12"),time ="00:00",area =c(lat_max, lon_min, lat_min, lon_max), # Formato: Norte, Oeste, Sul, Lesteformat ="netcdf",target =sprintf("era5_temperatura_favelas_%d.nc", ano) # Nome do arquivo de saída )# Executa a requisição arquivo_era5 <-wf_request(user = minha_api_key,request = request,transfer =TRUE,path =".",verbose =TRUE ) lista_arquivos[[as.character(ano)]] <- arquivo_era5cat(sprintf("✓ Download concluído para %d! Arquivo: %s\n", ano, arquivo_era5)) }return(lista_arquivos)}# Executa o download para todos os anosarquivos_era5 <-baixar_dados_serie_historica(anos, lat_max, lon_min, lat_min, lon_max, minha_api_key)cat("\n✓ Todos os downloads foram concluídos!")
Nota: O download pode demorar bastante tempo, pois estamos baixando 10 anos de dados. O status da sua requisição pode ser acompanhado em cds.climate.copernicus.eu/cdsapp/yourrequests.
Passo 5: Extrair a Temperatura para Cada Favela (Série Histórica)
Com os arquivos de dados climáticos (.nc) baixados, vamos abri-los e extrair a temperatura para a localização exata de cada favela ao longo do tempo.
Mostrar/Ocultar Código
# Função para extrair temperatura de um arquivo NetCDFextrair_temperatura_arquivo <-function(arquivo_nc, df_favelas_clean, ano) {# Carrega o arquivo NetCDF como um objeto raster raster_temp <-rast(arquivo_nc)# Converte a temperatura de Kelvin para Celsius raster_temp_celsius <- raster_temp -273.15# Converte o dataframe das favelas para um objeto espacial pontos_favelas <-vect( df_favelas_clean,geom =c("longitude", "latitude"),crs ="EPSG:4326"# Sistema de coordenadas padrão (WGS84) )# Extrai os valores de temperatura para cada ponto (favela)# O método 'bilinear' faz uma interpolação suave entre os pixels do raster temperaturas_extraidas <-extract(raster_temp_celsius, pontos_favelas, method ="bilinear")# Cria um dataframe com os resultados df_resultado <- df_favelas_clean %>%mutate(ano = ano,temperatura_c = temperaturas_extraidas[, 2] )return(df_resultado)}# Extrai temperatura de todos os arquivoslista_resultados <-list()for (ano in anos) { arquivo <- arquivos_era5[[as.character(ano)]]cat(sprintf("📊 Extraindo temperatura para o ano %d...\n", ano)) df_ano <-extrair_temperatura_arquivo(arquivo, df_favelas_clean, ano) lista_resultados[[as.character(ano)]] <- df_ano}# Combina todos os resultados em um único dataframedf_final_serie <-bind_rows(lista_resultados)cat("✓ Temperaturas extraídas com sucesso para toda a série histórica!\n")# Exibe as primeiras linhas do resultado finalhead(df_final_serie, 20)
Passo 6: Visualizar os Resultados da Série Histórica
A melhor forma de entender os dados é visualizando-os. Vamos criar visualizações para ver a distribuição espacial e temporal da temperatura.
6.1. Mapa de Calor Espacial
Mostrar/Ocultar Código
# Filtra dados do ano mais recente para visualização espacialdf_recente <- df_final_serie %>%filter(ano ==max(ano))# Cria o mapa de calorggplot(df_recente, aes(x = longitude, y = latitude, color = temperatura_c)) +# Adiciona os pontos no mapageom_point(size =3, alpha =0.8) +# Define a paleta de cores (de azul/frio para amarelo/quente)scale_color_viridis_c(option ="spectrum", name ="Temp. (°C)") +# Adiciona títulos e rótuloslabs(title ="Temperatura do Ar (ERA5) nas Favelas do Rio de Janeiro",subtitle =sprintf("Ano: %d", max(df_recente$ano)),x ="Longitude",y ="Latitude" ) +# Usa um tema limpo para o gráficotheme_minimal() +theme(plot.title =element_text(face ="bold", hjust =0.5),plot.subtitle =element_text(hjust =0.5))# Salva o gráfico em um arquivoggsave("mapa_temperatura_favelas_espacial.png", width =10, height =12, dpi =300)
6.2. Série Temporal
Mostrar/Ocultar Código
# Calcula a temperatura média por anodf_media_temporal <- df_final_serie %>%group_by(ano) %>%summarise(temperatura_media =mean(temperatura_c, na.rm =TRUE),temperatura_min =min(temperatura_c, na.rm =TRUE),temperatura_max =max(temperatura_c, na.rm =TRUE),.groups ='drop' )# Cria o gráfico de série temporalggplot(df_media_temporal, aes(x = ano, y = temperatura_media)) +# Adiciona a linha de tendênciageom_line(size =1, color ="#2E86AB") +# Adiciona os pontosgeom_point(size =3, color ="#2E86AB") +# Adiciona intervalo de confiança (min-max)geom_ribbon(aes(ymin = temperatura_min, ymax = temperatura_max), alpha =0.2, fill ="#2E86AB") +# Adiciona títulos e rótuloslabs(title ="Série Histórica de Temperatura (2016-2026)",subtitle ="Favelas do Rio de Janeiro - Dados ERA5",x ="Ano",y ="Temperatura Média (°C)" ) +# Usa um tema limpotheme_minimal() +theme(plot.title =element_text(face ="bold", hjust =0.5),plot.subtitle =element_text(hjust =0.5))# Salva o gráficoggsave("serie_temporal_temperatura_favelas.png", width =10, height =6, dpi =300)
Passo 7: Exportar os Dados em Formato Empilhado para Sistemas Web
Por fim, vamos exportar os dados em formato JSON empilhado (stacked), ideal para consumo por aplicações web e dashboards interativos.
7.1. Exportar em Formato JSON (Stacked)
Mostrar/Ocultar Código
# Cria a estrutura empilhada para JSONdados_empilhados <- df_final_serie %>%# Seleciona as colunas relevantesselect(id_favela = id,nome_favela = nome,estado = estado,cidade = cidade, latitude, longitude, ano, temperatura_c ) %>%# Converte para lista aninhadanest(dados_temperatura =-c(id_favela, nome_favela, estado, cidade, latitude, longitude)) %>%mutate(dados_temperatura =map(dados_temperatura, ~list(historico = .x %>%arrange(ano) %>%pmap(function(ano, temperatura_c) {list(ano = ano, temperatura_celsius = temperatura_c) }) )) )# Exporta para JSONjson_output <-toJSON(dados_empilhados, pretty =TRUE, auto_unbox =TRUE)write(json_output, "favelas_temperatura_stacked.json")cat("✓ Dados exportados em formato JSON empilhado: 'favelas_temperatura_stacked.json'\n")
7.2. Exportar em Formato CSV (Tradicional)
Mostrar/Ocultar Código
# Salva o dataframe final em um arquivo CSVwrite.csv(df_final_serie, "favelas_com_temperatura_serie_historica.csv", row.names =FALSE, fileEncoding ="UTF-8")cat("✓ Resultados finais exportados para 'favelas_com_temperatura_serie_historica.csv'\n")
7.3. Exportar em Formato JSON (Formato Tabular)
Mostrar/Ocultar Código
# Exporta em formato tabular (mais simples para web)json_tabular <-toJSON(df_final_serie, pretty =TRUE)write(json_tabular, "favelas_temperatura_tabular.json")cat("✓ Dados exportados em formato JSON tabular: 'favelas_temperatura_tabular.json'\n")
Antes de usar os dados em produção, é importante validar a qualidade.
Mostrar/Ocultar Código
# Verifica valores ausentescat("📊 Análise de Qualidade dos Dados:\n")cat(sprintf("Total de registros: %d\n", nrow(df_final_serie)))cat(sprintf("Registros com temperatura válida: %d (%.2f%%)\n", sum(!is.na(df_final_serie$temperatura_c)),100*sum(!is.na(df_final_serie$temperatura_c)) /nrow(df_final_serie)))# Estatísticas descritivascat("\n📈 Estatísticas Descritivas:\n")print(summary(df_final_serie$temperatura_c))# Verifica outliers (valores fora de 3 desvios padrão)media <-mean(df_final_serie$temperatura_c, na.rm =TRUE)desvio <-sd(df_final_serie$temperatura_c, na.rm =TRUE)outliers <- df_final_serie %>%filter(abs(temperatura_c - media) >3* desvio)cat(sprintf("\n⚠️ Possíveis outliers (>3σ): %d registros\n", nrow(outliers)))if (nrow(outliers) >0) {print(outliers %>%select(nome, ano, temperatura_c))}
Conclusão
Parabéns! Você completou o tutorial de análise de temperatura ERA5 para favelas com série histórica. Os dados estão prontos para serem consumidos por sistemas web, dashboards interativos e análises posteriores.
Próximos Passos
Integre os arquivos JSON em um dashboard web (ex: Shiny, Plotly, D3.js)
Realize análises de tendência e mudanças climáticas
Compare os dados entre diferentes favelas e regiões