Este informe analiza una base de datos meteorológica histórica con el objetivo de identificar patrones y relaciones entre variables climáticas clave. Las preguntas planteadas se responden utilizando análisis estadísticos como pruebas t, regresiones lineales, ANOVA y visualizaciones atractivas que destacan las tendencias.
Antes de realizar análisis específicos, examinamos la estructura de los datos para comprender sus características principales.
data <- read.csv("weatherHistory.csv")
head(data)
## Formatted.Date Summary Precip.Type Temperature..C.
## 1 2006-04-01 00:00:00.000 +0200 Partly Cloudy rain 9.472222
## 2 2006-04-01 01:00:00.000 +0200 Partly Cloudy rain 9.355556
## 3 2006-04-01 02:00:00.000 +0200 Mostly Cloudy rain 9.377778
## 4 2006-04-01 03:00:00.000 +0200 Partly Cloudy rain 8.288889
## 5 2006-04-01 04:00:00.000 +0200 Mostly Cloudy rain 8.755556
## 6 2006-04-01 05:00:00.000 +0200 Partly Cloudy rain 9.222222
## Apparent.Temperature..C. Humidity Wind.Speed..km.h. Wind.Bearing..degrees.
## 1 7.388889 0.89 14.1197 251
## 2 7.227778 0.86 14.2646 259
## 3 9.377778 0.89 3.9284 204
## 4 5.944444 0.83 14.1036 269
## 5 6.977778 0.83 11.0446 259
## 6 7.111111 0.85 13.9587 258
## Visibility..km. Loud.Cover Pressure..millibars.
## 1 15.8263 0 1015.13
## 2 15.8263 0 1015.63
## 3 14.9569 0 1015.94
## 4 15.8263 0 1016.41
## 5 15.8263 0 1016.51
## 6 14.9569 0 1016.66
## Daily.Summary
## 1 Partly cloudy throughout the day.
## 2 Partly cloudy throughout the day.
## 3 Partly cloudy throughout the day.
## 4 Partly cloudy throughout the day.
## 5 Partly cloudy throughout the day.
## 6 Partly cloudy throughout the day.
summary(data)
## Formatted.Date Summary Precip.Type Temperature..C.
## Length:96453 Length:96453 Length:96453 Min. :-21.822
## Class :character Class :character Class :character 1st Qu.: 4.689
## Mode :character Mode :character Mode :character Median : 12.000
## Mean : 11.933
## 3rd Qu.: 18.839
## Max. : 39.906
## Apparent.Temperature..C. Humidity Wind.Speed..km.h.
## Min. :-27.717 Min. :0.0000 Min. : 0.000
## 1st Qu.: 2.311 1st Qu.:0.6000 1st Qu.: 5.828
## Median : 12.000 Median :0.7800 Median : 9.966
## Mean : 10.855 Mean :0.7349 Mean :10.811
## 3rd Qu.: 18.839 3rd Qu.:0.8900 3rd Qu.:14.136
## Max. : 39.344 Max. :1.0000 Max. :63.853
## Wind.Bearing..degrees. Visibility..km. Loud.Cover Pressure..millibars.
## Min. : 0.0 Min. : 0.00 Min. :0 Min. : 0
## 1st Qu.:116.0 1st Qu.: 8.34 1st Qu.:0 1st Qu.:1012
## Median :180.0 Median :10.05 Median :0 Median :1016
## Mean :187.5 Mean :10.35 Mean :0 Mean :1003
## 3rd Qu.:290.0 3rd Qu.:14.81 3rd Qu.:0 3rd Qu.:1021
## Max. :359.0 Max. :16.10 Max. :0 Max. :1046
## Daily.Summary
## Length:96453
## Class :character
## Mode :character
##
##
##
str(data)
## 'data.frame': 96453 obs. of 12 variables:
## $ Formatted.Date : chr "2006-04-01 00:00:00.000 +0200" "2006-04-01 01:00:00.000 +0200" "2006-04-01 02:00:00.000 +0200" "2006-04-01 03:00:00.000 +0200" ...
## $ Summary : chr "Partly Cloudy" "Partly Cloudy" "Mostly Cloudy" "Partly Cloudy" ...
## $ Precip.Type : chr "rain" "rain" "rain" "rain" ...
## $ Temperature..C. : num 9.47 9.36 9.38 8.29 8.76 ...
## $ Apparent.Temperature..C.: num 7.39 7.23 9.38 5.94 6.98 ...
## $ Humidity : num 0.89 0.86 0.89 0.83 0.83 0.85 0.95 0.89 0.82 0.72 ...
## $ Wind.Speed..km.h. : num 14.12 14.26 3.93 14.1 11.04 ...
## $ Wind.Bearing..degrees. : num 251 259 204 269 259 258 259 260 259 279 ...
## $ Visibility..km. : num 15.8 15.8 15 15.8 15.8 ...
## $ Loud.Cover : num 0 0 0 0 0 0 0 0 0 0 ...
## $ Pressure..millibars. : num 1015 1016 1016 1016 1017 ...
## $ Daily.Summary : chr "Partly cloudy throughout the day." "Partly cloudy throughout the day." "Partly cloudy throughout the day." "Partly cloudy throughout the day." ...
# Filtrar datos
rain_data <- data %>% filter(Precip.Type == "rain")
no_rain_data <- data %>% filter(Precip.Type != "rain")
# Prueba t para la temperatura
temp_ttest <- t.test(rain_data$Temperature..C., no_rain_data$Temperature..C.)
temp_ttest
##
## Welch Two Sample t-test
##
## data: rain_data$Temperature..C. and no_rain_data$Temperature..C.
## t = 334.5, df = 24491, p-value < 2.2e-16
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
## 16.39811 16.59142
## sample estimates:
## mean of x mean of y
## 13.852989 -2.641778
# Gráfico de distribución
ggplot(data, aes(x = Precip.Type, y = Temperature..C., fill = Precip.Type)) +
geom_boxplot(alpha = 0.7) +
scale_fill_manual(values = c("rain" = "#3498db", "other" = "#e74c3c")) +
labs(title = "Distribución de Temperatura por Tipo de Precipitación",
x = "Tipo de Precipitación", y = "Temperatura (°C)") +
theme_minimal()
En esta sección, analizamos si la hora del día tiene un efecto significativo sobre la temperatura promedio. Para ello, utilizaremos un análisis de varianza (ANOVA) junto con una visualización colorida en forma de boxplots.
weather_data$Hour <- as.numeric(format(as.POSIXct(weather_data$Formatted.Date, format="%Y-%m-%d %H:%M:%S"), "%H"))
# ANOVA para temperatura según la hora del día
anova_hour <- aov(Temperature..C. ~ as.factor(Hour), data = weather_data)
summary(anova_hour)
## Df Sum Sq Mean Sq F value Pr(>F)
## as.factor(Hour) 23 878819 38210 465.2 <2e-16 ***
## Residuals 96429 7920693 82
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# Gráfico
weather_data$Formatted.Date <- as.POSIXct(weather_data$Formatted.Date, format = "%Y-%m-%d %H:%M:%S")
weather_data$Hour <- format(weather_data$Formatted.Date, "%H")
hourly_means <- weather_data %>%
group_by(Hour) %>%
summarise(mean_temperature = mean(Temperature..C., na.rm = TRUE))
weather_data <- merge(weather_data, hourly_means, by = "Hour")
# Crear el boxplot
ggplot(weather_data, aes(x = as.factor(Hour), y = Temperature..C., fill = mean_temperature)) +
geom_boxplot(outlier.color = "black", outlier.shape = 16, outlier.size = 2) +
scale_fill_gradient(low = "blue", high = "red", name = "Temperatura Media (C)") + # Gradiente azul-rojo
theme_minimal(base_size = 14) +
theme(legend.position = "right",
panel.grid.major = element_line(color = "grey"),
plot.title = element_text(face = "bold", hjust = 0.5)) +
labs(title = "Distribución de Temperatura por Hora del Día",
x = "Hora del Día", y = "Temperatura (C)")
Este gráfico destaca las diferencias entre las horas del día con colores vivos, facilitando la interpretación visual de los resultados. Como podemos observar, cuanto más azul sea el color del boxplot relacionado a esa hora del día, más fría será su temperatura media, y cuanto más rojo sea, más cálida será esa hora en media.
¿Cómo se relaciona la humedad con la temperatura?
# Regresión lineal simple
simple_model <- lm(Temperature..C. ~ Humidity, data = weather_data)
summary(simple_model)
##
## Call:
## lm(formula = Temperature..C. ~ Humidity, data = weather_data)
##
## Residuals:
## Min 1Q Median 3Q Max
## -52.415 -5.091 0.378 5.741 18.804
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 34.6369 0.0927 373.7 <2e-16 ***
## Humidity -30.8944 0.1219 -253.4 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 7.4 on 96451 degrees of freedom
## Multiple R-squared: 0.3997, Adjusted R-squared: 0.3997
## F-statistic: 6.423e+04 on 1 and 96451 DF, p-value: < 2.2e-16
# Visualización
ggplot(weather_data, aes(x = Humidity, y = Temperature..C.)) +
geom_point(alpha = 0.3, color = "pink") +
geom_smooth(method = "lm", color = "light blue") +
labs(title = "Relación entre Humedad y Temperatura",
x = "Humedad", y = "Temperatura (C)")
## `geom_smooth()` using formula 'y ~ x'
Este análisis nos permite visualizar muy claramente, la dependencia de la humedad con la temperatura. Como se puede observar, a mayor temperatura, menor es la humedad media, y a medida que disminuye la temperatura, aumenta la humedad, siguiendo una distribución lineal.
# con este código obtenemos 5 de las opciones climaticas mas frecuentes
top_summaries <- data %>%
count(Daily.Summary, sort = TRUE) %>%
top_n(5, n)
filtered_data <- data %>% filter(Daily.Summary %in% top_summaries$Daily.Summary)
# Gráfico
ggplot(filtered_data, aes(x = Daily.Summary, y = Temperature..C., fill = Daily.Summary)) +
geom_boxplot(alpha = 0.7) +
scale_fill_brewer(palette = "Set3") +
labs(title = "Distribución de Temperaturas por Resumen Diario",
x = "Resumen Diario", y = "Temperatura (°C)") +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
En esta pregunta, se comparan las temperaturas según el parte diario de la condición meteorológica. Se han seleccionado 5 de todas las posibles opciones, y en ellas observamos que los días en los que por la mañana está nublado (por niebla no por nubes) son los días en los que acostumbra a hacer más frío.
data <- data %>%
mutate(Temp.Group = cut(Temperature..C., breaks = c(-10, 0, 10, 20, 30), labels = c("Muy Baja", "Baja", "Media", "Alta")))
anova_wind_temp <- aov(Wind.Speed..km.h. ~ Temp.Group, data = data)
summary(anova_wind_temp)
## Df Sum Sq Mean Sq F value Pr(>F)
## Temp.Group 3 41357 13786 287.8 <2e-16 ***
## Residuals 93282 4468781 48
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 3167 observations deleted due to missingness
# Gráfico
ggplot(data, aes(x = Temp.Group, y = Wind.Speed..km.h., fill = Temp.Group)) +
geom_boxplot(alpha = 0.8) +
scale_fill_brewer(palette = "Set2") +
labs(title = "Velocidad del Viento por Rango de Temperatura",
x = "Rango de Temperatura", y = "Velocidad del Viento (km/h)") +
theme_minimal()
En este estudio, realizamos un análisis de datos meteorológicos históricos utilizando técnicas estadísticas, para responder preguntas clave sobre el comportamiento climático. Comparamos principalmente las diferencias de temperatura entre días con y sin lluvia mediante t.tests, analizamos cómo la hora del día influye en la temperatura promedio con ANOVA y boxplots, e identificamos relaciones entre humedad y temperatura utilizando regresión lineal simple. Además, examinamos la distribución de temperaturas según resúmenes diarios del clima y evaluamos cómo la velocidad del viento varía en diferentes rangos de temperatura.
Estos datos son acompañados por visualizaciones gráficas, para facilitar la interpretación de los datos.