La idea de este breve artículo es mostrar una función para descargar datos desde el sitio del Servicio Meteorológico Nacional SMN y ,al mismo tiempo, entrenar el uso de funciones y bucles para un fin determinado.
En la sección Descarga del Catálogo de Datos Abiertos del SMN y luego de dar conformidad al acuerdo, es posible acceder a los datos diarios que el servicio pone a disposición, tal cual se ve en la siguiente imágen:
Puede apreciarse todos los tipos de datos que brinda el sitio. A los fines de este artículo, optaremos por descargar los datos horarios (DF) a los cuales es posible acceder “clickeando” en el día buscado. Se puede ver que el enlace que lleva a la descarga del dato contiene su fecha:
Por lo tanto, si lo que buscamos es efectuar varias descargas (por ejemplo todo un mes de observaciones) es necesario generar un objeto fecha que contenga los días buscados para automatizar las descargas mediante un bucle.
Generar un data frame que contenga las temperaturas mínimas y máximas de cada día junto con el valor de humedad promedio
Arranquemos!
#se borran todos los objetos de la memoria
rm(list =ls())
#Se instalan librerías de trabajo
library(tidyverse) # Para limpieza y manipulación de datos
library(lubridate) # Para trabajar con fechas
setwd("C:/Users/Guille/Documents/Proyectos/WebScrapping/clima/Scrap_smn")
En este ejemplo vamos a intentar descargar observaciones desde el
01-07-2023 hasta el 31-07-2023 en la Ciudad Autónoma de Buenos Aires.
Cada información diaria descargada contiene la información por hora y
por observatorio. Vamos a tomar los primeros 24 valores correspondientes
al observatorio de Aeroparque. Vamos a definir los objetos
fecha_inicial y fecha_final para generar una
secuencia de fechas a las que, finalmente, limpiaremos para que queden
con el formato del link de descarga
fecha_inicial <- ymd("2023-07-01")
fecha_final <- ymd("2023-07-31")
fechas <- seq.Date(fecha_inicial,fecha_final, by = "day") #aux para crear listado de fechas
list <- paste0(substr(fechas,1,4),substr(fechas,6,7),substr(fechas,9,10)) #lista que servirá de insumo para iterar
Ya tenemos nuestra lista, ahora vamos pensar un bucle for que itere los elementos de la misma con el objetivo de descargar la información y devolver un data frame, pero antes generamos un df vacío llamado dataclima en donde incorporaremos nuestras descargas:
dataclima <- data.frame()
for (i in list){
linkday <- glue::glue("https://ssl.smn.gob.ar/dpd/descarga_opendata.php?file=observaciones/datohorario{i}.txt") #link para descargar con la variable fecha
day <- read.table(linkday, skip = 2, nrows = 24) #tabla con los datos descargados, se especifican las 23 primeras filas porque son las que corresponden a CABA
dataclima <- rbind(dataclima,day) #se suman las filas diarias
print(glue::glue("Fecha: {i}")) #a modo de control, se imprime las fechas de descagas
print(glue::glue("se descargaron {nrow(dataclima)} datos"))
}
Fecha: 20230701
se descargaron 24 datos
Fecha: 20230702
se descargaron 48 datos
Fecha: 20230703
se descargaron 72 datos
Fecha: 20230704
se descargaron 96 datos
Fecha: 20230705
se descargaron 120 datos
Fecha: 20230706
se descargaron 144 datos
Fecha: 20230707
se descargaron 168 datos
Fecha: 20230708
se descargaron 192 datos
Fecha: 20230709
se descargaron 216 datos
Fecha: 20230710
se descargaron 240 datos
Fecha: 20230711
se descargaron 264 datos
Fecha: 20230712
se descargaron 288 datos
Fecha: 20230713
se descargaron 312 datos
Fecha: 20230714
se descargaron 336 datos
Fecha: 20230715
se descargaron 360 datos
Fecha: 20230716
se descargaron 384 datos
Fecha: 20230717
se descargaron 408 datos
Fecha: 20230718
se descargaron 432 datos
Fecha: 20230719
se descargaron 456 datos
Fecha: 20230720
se descargaron 480 datos
Fecha: 20230721
se descargaron 504 datos
Fecha: 20230722
se descargaron 528 datos
Fecha: 20230723
se descargaron 552 datos
Fecha: 20230724
se descargaron 576 datos
Fecha: 20230725
se descargaron 600 datos
Fecha: 20230726
se descargaron 624 datos
Fecha: 20230727
se descargaron 648 datos
Fecha: 20230728
se descargaron 672 datos
Fecha: 20230729
se descargaron 696 datos
Fecha: 20230730
se descargaron 720 datos
Fecha: 20230731
se descargaron 744 datos
Ya tenemos nuestro df con las observaciones, veamos que contiene
summary(dataclima)
V1 V2 V3 V4 V5 V6 V7 V8 V9
Min. : 1072023 Min. : 0.00 Min. : 4.30 Min. :38.00 Min. :1002 Min. : 0 Min. : 0.00 Length:744 Length:744
1st Qu.: 8072023 1st Qu.: 5.75 1st Qu.:10.20 1st Qu.:68.00 1st Qu.:1016 1st Qu.: 90 1st Qu.: 7.00 Class :character Class :character
Median :16072023 Median :11.50 Median :12.50 Median :77.00 Median :1019 Median :145 Median :13.00 Mode :character Mode :character
Mean :16072023 Mean :11.50 Mean :12.60 Mean :75.58 Mean :1020 Mean :214 Mean :13.41
3rd Qu.:24072023 3rd Qu.:17.25 3rd Qu.:14.72 3rd Qu.:85.00 3rd Qu.:1024 3rd Qu.:300 3rd Qu.:17.50
Max. :31072023 Max. :23.00 Max. :26.00 Max. :97.00 Max. :1034 Max. :990 Max. :41.00
glimpse(dataclima)
Rows: 744
Columns: 9
$ V1 <int> 1072023, 1072023, 1072023, 1072023, 1072023, 1072023, 1072023, 1072023, 1072023, 1072023, 1072023, 1072023, 1072023, 1072023, 1072023, 1072023, 1072023, 1…
$ V2 <int> 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19…
$ V3 <dbl> 13.4, 13.2, 13.0, 12.7, 12.4, 12.2, 12.0, 11.7, 11.6, 11.9, 13.5, 13.9, 13.8, 14.0, 13.4, 13.5, 14.1, 13.9, 12.6, 12.8, 12.9, 12.8, 13.1, 13.5, 13.7, 14.1…
$ V4 <int> 74, 75, 76, 77, 79, 79, 81, 83, 85, 84, 80, 78, 79, 79, 82, 80, 78, 77, 87, 87, 88, 92, 91, 88, 87, 86, 89, 86, 94, 90, 90, 90, 91, 89, 88, 83, 84, 83, 84…
$ V5 <dbl> 1024.2, 1023.6, 1023.8, 1023.5, 1023.0, 1022.4, 1022.4, 1022.4, 1023.0, 1023.5, 1023.8, 1024.0, 1022.7, 1022.1, 1021.3, 1020.9, 1020.3, 1019.9, 1020.0, 10…
$ V6 <int> 50, 50, 40, 20, 30, 30, 20, 360, 10, 990, 70, 40, 60, 40, 70, 90, 90, 100, 100, 100, 90, 100, 90, 80, 50, 10, 350, 50, 90, 90, 80, 80, 60, 60, 60, 60, 70,…
$ V7 <int> 13, 13, 9, 6, 6, 6, 7, 11, 6, 4, 6, 7, 9, 7, 9, 13, 17, 17, 17, 19, 17, 19, 17, 13, 9, 7, 7, 9, 9, 11, 13, 11, 11, 13, 13, 13, 9, 13, 13, 19, 15, 7, 11, 1…
$ V8 <chr> "AEROPARQUE", "AEROPARQUE", "AEROPARQUE", "AEROPARQUE", "AEROPARQUE", "AEROPARQUE", "AEROPARQUE", "AEROPARQUE", "AEROPARQUE", "AEROPARQUE", "AEROPARQUE", …
$ V9 <chr> "AERO", "AERO", "AERO", "AERO", "AERO", "AERO", "AERO", "AERO", "AERO", "AERO", "AERO", "AERO", "AERO", "AERO", "AERO", "AERO", "AERO", "AERO", "AERO", "A…
Dado que decidimos esquivar las primeras filas para no obtener errores, no sabemos los nombres de las columnas, Vamos a descargar solamente un día para obtener el nombre d de las variables.
linkprueba <- glue::glue("https://ssl.smn.gob.ar/dpd/descarga_opendata.php?file=observaciones/datohorario20240702.txt") #link para descargar con la variable fecha
dayprueba <- read.table(linkprueba,nrows = 1)
dayprueba
NA
Ya tenemos los nombres y podemos ver toda la información que brinda el smn en la modalidad datos horarios. A los fines de cumplir con el objetivo planteado. Vamos a crear un dataframe tomando el día como unidad y captando la temperatura máxima, la mínima y la media de humedad.
df <- dataclima %>%
select(Fecha = V1,
Hora = V2,
Temp = V3,
Humedad = V4) %>%
group_by(Fecha) %>%
summarise(Temp_Min = min(Temp),
Temp_Max = max(Temp),
Humedad_Media = round(mean(Humedad),2)) %>%
mutate(Fecha = dmy(Fecha)) %>%
arrange(Fecha)
df
NA
Vamos a graficar nuestros datos, para lo cual procedemos a pivotear la tabla
library(ggtext)
tabla1 <- df %>%
pivot_longer(cols = c(Temp_Min,Temp_Max,Humedad_Media),
names_to = "Variables",
values_to = "Valores")
ggplot(tabla1, aes(x = Fecha, y = Valores, color = Variables))+
geom_line()+
geom_point()+
scale_color_manual(values = c("Temp_Min" = "#118ab2",
"Temp_Max" = "#ef476f",
"Humedad_Media" = "#122c91"))+
labs(title = "Valores climáticos del mes de julio-2023 de<br><b style='color:#122c91;'>Humedad</b>, <b style='color:#ef476f;'>Temperatura Máxima</b> y <b style='color:#118ab2;'>Temperatura Mínima</b>",
caption = "<b>Fuente</b>: Servicio Meteorológico Nacional")+
theme_minimal()+
theme(legend.position = "none",
panel.grid.minor = element_blank(),
plot.title = element_markdown(margin=margin(0,0,10,-30),
size=12),
plot.caption = element_markdown(size = 11))
NA
NA
NA
Para finalizar, podemos armar una función con todos los pasos del proceso
get_datos_horarios <- function(fecha_ini,fecha_fin){
fecha_inicial <- ymd(fecha_ini)
fecha_final <- ymd(fecha_fin)
fechas <- seq.Date(fecha_inicial,fecha_final, by = "day") #aux para crear listado de fechas
list <- paste0(substr(fechas,1,4),substr(fechas,6,7),substr(fechas,9,10)) #lista que servirá de insumo para iterar
dataclima <- data.frame()
for (i in list){
linkday <- glue::glue("data/datohorario{i}.txt") #link para descargar con la variable fecha
day <- read.table(linkday, skip = 2, nrows = 24) #tabla con los datos descargados, se especifican las 23 primeras filas porque son las que corresponden a CABA
dataclima <- rbind(dataclima,day) #se suman las filas diarias
print(glue::glue("Fecha: {i}")) #a modo de control, se imprime las fechas de descagas
print(glue::glue("se descargaron {nrow(dataclima)} datos horarios"))
}
dataclima <- dataclima %>%
select(Fecha = V1,
Hora = V2,
Temp = V3,
Humedad = V4) %>%
group_by(Fecha) %>%
summarise(Temp_Min = min(Temp),
Temp_Max = max(Temp),
Humedad_Media = round(mean(Humedad),2)) %>%
mutate(Fecha = dmy(Fecha)) %>%
arrange(Fecha)
return(dataclima)
}