0. librerias

library(readr)
library(dplyr)
library(knitr)
library(kableExtra)
library(ggplot2)

1. Leer datos

Cargamos el conjunto de datos meteorológicos globales.

variables <- read.csv("C:/Users/dellh/Downloads/GlobalWeatherRepository.csv")

2. Selección (causa y efecto)

                            Elegimos analizar

Variable \(X\) (Causa): Índice UV (uv_index).La radiación ultravioleta es la fuente primaria de energía solar que entra a la atmósfera.

Variable \(Y\) (Efecto): Temperatura (temperature_c). La acumulación de esta radiación en la superficie incrementa la temperatura del aire

# X (Causa) = Índice UV (uv_index)
# Y (Efecto) = Temperatura en °C (temperature_celsius)

y <- as.numeric(variables$temperature_celsius)
x <- as.numeric(variables$uv_index)
TPP <- data.frame(y, x)

3. Tabla de pares de valores

Verificamos que ambas variables tengan el mismo tamaño muestral limpios para evitar errores para proceder a realizar la tabla y los gráficos.

3.1. Tamaño muestra

limpiar_columna_exacta <- function(df, cols) {
  for (col in cols) {
    temp_col <- as.character(df[[col]])
    temp_col[is.na(temp_col) | temp_col == "" | temp_col == " "] <- "0"
    df[[col]] <- as.numeric(temp_col)
    df[[col]][is.na(df[[col]])] <- 0
  }
  return(df)
}

datos_limpios <- limpiar_columna_exacta(variables, c("uv_index", "temperature_celsius"))
n_total <- nrow(datos_limpios)
cat("Tamaño muestral total depurado (n) = ", n_total, "\n")
## Tamaño muestral total depurado (n) =  141703

3.2. Extracto de tabla

extraer_diez_filas <- head(data.frame(
  `Índice UV (Causa)` = datos_limpios$uv_index,
  `Temperatura C (Efecto)` = datos_limpios$temperature_celsius,
  check.names = FALSE
), 10)

tabla_mostrar <- as.data.frame(lapply(extraer_diez_filas, as.character))


n_total_real <- 141703

# 4. Agregamos la fila final del Total (n)
tabla_con_total <- rbind(tabla_mostrar, c(n_total_real, n_total_real))
rownames(tabla_con_total) <- c(1:10, "Total (n)")

# 5. Generar y mostrar la tabla visualmente
tabla_resultado <- kable(
  tabla_con_total,
  align = "c", 
  booktabs = TRUE,
  caption = "Tabla N°1: Pares de valores de Índice UV y Temperatura (°C), Estudio Global 2024-2026"
) %>%
  kable_styling(bootstrap_options = c("striped", "hover", "condensed"), full_width = FALSE, position = "center") %>%
  row_spec(0, bold = TRUE, color = "#2B2D42", background = "#A0C4FF") %>%
  row_spec(11, bold = TRUE, color = "#2B2D42", background = "#CAFFBF") %>%
  footnote(
    general = "Fuente: Global Weather Repository,(https://www.kaggle.com/datasets/nelgiriyewithana/global-weather-repository)",
    general_title = "Nota:Grupo N°2 ", 
    footnote_as_chunk = TRUE
  )

tabla_resultado
Tabla N°1: Pares de valores de Índice UV y Temperatura (°C), Estudio Global 2024-2026
Índice.UV..Causa. Temperatura.C..Efecto.
1 7 26.6
2 5 19
3 5 23
4 2 6.3
5 8 26
6 1 26
7 1 8
8 4 19
9 1 9
10 5 16
Total (n) 141703 141703
Nota:Grupo N°2 Fuente: Global Weather Repository,(https://www.kaggle.com/datasets/nelgiriyewithana/global-weather-repository)

4. Gráfica de Dispersión

4.1. Gráfica de dispersión original

ggplot(datos_limpios, aes(x = uv_index, y = temperature_celsius)) +
  geom_point(alpha = 0.25, color = "#00A8E8", size = 1.2) +
  coord_cartesian(xlim = c(0, NA), ylim = c(0, NA)) +
  theme_minimal() +
  labs(
    title = "Gráfico N°1: Relación entre Temperatura (°C) frente al Índice UV\nPeríodo 2024-2026",
    subtitle = paste("Datos originales con dispersión ambiental natural | n =", n_total, "registros"),
    x = "Índice UV",
    y = "Temperatura (°C)"
  ) +
  theme(
    plot.title = element_text(face = "bold", size = 12, hjust = 0.5, color = "#2B2D42"),
    plot.subtitle = element_text(size = 10, hjust = 0.5, color = "#555555"),
    panel.background = element_rect(fill = "#FAFAFA", color = NA),
    panel.border = element_rect(color = "#BDBDBD", fill = NA, linewidth = 1)
  )

4.2. Tratamiento de datos

Agrupamos los datos en 100 percentiles según el Índice UV para obtener la tendencia central del fenómeno sin dispersión extrema.

datos_percentiles <- datos_limpios %>%
  filter(uv_index > 0 & temperature_celsius > 0) %>%
  mutate(percentil = ntile(uv_index, 100)) %>%
  group_by(percentil) %>%
  summarise(
    UV_Promedio = mean(uv_index, na.rm = TRUE),
    Temp_Promedio = mean(temperature_celsius, na.rm = TRUE)
  )

x_tratado <- datos_percentiles$UV_Promedio
y_tratado <- datos_percentiles$Temp_Promedio

4.3. Gráfica de Dispersión simplificada

par(bg = "#FAFAFA")
plot(
  x_tratado, y_tratado, type = "p", pch = 19, col = "#00A8E8",
  main = "Gráfico N°2: Temperatura Promedio por Percentiles de Índice UV\nPeríodo 2024-2026",
  xlab = "Índice UV Promedio", ylab = "Temperatura Promedio (°C)",
  col.main = "#2B2D42", col.lab = "#2B2D42"
)

5.Conjetura

Observamos que a mayor nivel de radiación UV (\(X\)), se produce un incremento en la temperatura (\(Y\)).

Proponemos un Modelo Potencial (\(Y = a \cdot X^b\)) para explicar este crecimiento.

6. Cálculos de Parámetros

Ajustamos mediante logaritmos: \(\ln(Y) = \ln(a) + b \cdot \ln(X)\).

regresion_potencial <- lm(log(y_tratado) ~ log(x_tratado))

b_coef <- regresion_potencial$coefficients[2]
a_coef <- exp(regresion_potencial$coefficients[1])

a_val <- round(a_coef, 4)
b_val <- round(b_coef, 4)

par(bg = "#FAFAFA", mar = c(1, 1, 1, 1))
plot(1:10, 1:10, type = "n", xlab = "", ylab = "", axes = FALSE, main = "Ecuación del Modelo Matemático Potencial")
rect(1, 3, 10, 8, col = "#E8AE20B7", border = "#FFB5A7", lwd = 3)
text(5.5, 6.2, labels = "Modelo de Regresión Potencial (Y = a * X^b)", cex = 1.2, font = 2, col = "#2B2D42")
text(5.5, 4.5, labels = paste0("Temperatura = ", a_val, " * (Índice UV)^(", b_val, ")"), cex = 1.1, font = 4, col = "#D62828")

                             Donde:

\(X\): Índice UV (Causa)

\(Y\): Temperatura en \(^{\circ}\text{C}\) (Efecto)

\(a = 18.2826\): Coeficiente de escala.

\(b = 0.1847\): Exponente del modelo (\(b > 0\), indica crecimiento directo).

7. Sobreponer la realidad con el modelo

# Visualizamos la curva ajustada del modelo potencial sobre los datos tratados

par(bg = "#FAFAFA")
plot(
  x_tratado, y_tratado, type = "p", pch = 19, col = "#00A8E8",
  main = "Gráfico N°3: Ajuste del Modelo Potencial Temperatura vs Índice UV\nPeríodo 2024-2026",
  xlab = "Índice UV Promedio", ylab = "Temperatura Promedio (°C)",
  col.main = "#2B2D42", col.lab = "#2B2D42"
)

x_seq <- seq(min(x_tratado), max(x_tratado), length.out = 1000)
y_pred_seq <- a_coef * (x_seq ^ b_coef)

lines(x_seq, y_pred_seq, col = "red", lwd = 2.5)
legend("bottomright", legend = paste0("Modelo Potencial (Y = ", a_val, " * X^", b_val, ")"), 
       col = "red", lty = 1, lwd = 2.5, bty = "n")

8. Test de bondad

r_potencial <- cor(log(y_tratado), log(x_tratado), use = "complete.obs")
r2_potencial <- r_potencial^2

cat("Coeficiente de Correlación (r):", round(r_potencial, 4), "\n")
## Coeficiente de Correlación (r): 0.8738
cat("Coeficiente de Determinación (R²):", round(r2_potencial, 4), "\n")
## Coeficiente de Determinación (R²): 0.7635

9. Restricciones

# Dominio [X]: Índice UV -> D = {x ∈ ℝ | x ≥ 0}
# Dominio [Y]: Temperatura (°C) -> R = {y ∈ ℝ | y > 0}
                          Restricciones:
                          

#Dominio (\(X \ge 0\)): El Índice UV no puede ser negativo por definición.

#Dominio (\(Y > 0\)): Por la naturaleza matemática de la función potencial (\(Y = a \cdot X^b\)), el modelo solo genera estimaciones térmicas positivas. Por tanto, no es aplicable para predecir temperaturas bajo cero (\(0^\circ\text{C}\) o menores).

10. Estimaciones

¿Qué Temperatura se espera cuando el Índice UV alcanza un nivel alto de \(X = 10\) puntos?

# Valor evaluado: X = 10 (Índice UV alto)
# Comparación desde X = 3 (Índice UV moderado)

Temp_10 <- round(a_coef * ((10 + 0.0001)^b_coef), 2)

Temp_3 <- a_coef * ((3 + 0.0001)^b_coef)
Temp_10_real <- a_coef * ((10 + 0.0001)^b_coef)

incremento_porcentaje <- ((Temp_10_real - Temp_3) / Temp_3) * 100

par(mar = c(0.5, 0.5, 0.5, 0.5))
plot(0, 0, type = "n", xlim = c(0, 10), ylim = c(0, 10), axes = FALSE, xlab = "", ylab = "")

# Panel 1: Pregunta de Cantidad
rect(0.2, 5.2, 9.8, 9.8, col = "#EBF5FB", border = "#1F4E79", lwd = 2)
text(
  x = 5, y = 7.5,
  labels = paste0(
    "1. Pregunta de Cantidad\n\n",
    "¿Qué temperatura se espera cuando la radiación UV alcanza X = 10 puntos?\n\n",
    "Resultado Estimado: ", Temp_10, " °C"
  ),
  cex = 0.95, col = "#1F4E79", font = 2
)

# Panel 2: Pregunta de Porcentaje
rect(0.2, 0.2, 9.8, 4.9, col = "#FEF9E7", border = "#B7950B", lwd = 2)
text(
  x = 5, y = 2.55,
  labels = paste0(
    "2. Pregunta de Porcentaje\n\n",
    "¿En qué porcentaje aumenta la temperatura si el Índice UV sube\n",
    "de un nivel moderado (3 puntos) a un nivel muy alto (10 puntos)?\n\n",
    "Resultado: +", round(incremento_porcentaje, 2), " %"
  ),
  cex = 0.95, col = "#B7950B", font = 2
)

11. Conclusión

El Índice UV (\(X\)) explica la Temperatura (\(Y\)) mediante el modelo potencial \(Y = 18.2826 \cdot X^{0.1847}\). A mayor radiación ultravioleta registrada, la temperatura responde de forma ascendente. El modelo respeta las restricciones (\(X \ge 0\), \(Y > 0\)) y estima que para un Índice UV de 10 puntos, la temperatura esperada es de r Temp_10 \(^{\circ}\text{C}\).