Prefacio: Contexto de la Competición y Filosofía del EDA

La Competición Kaggle

Este Análisis Exploratorio de Datos (EDA) se enmarca en la competición “Predicting Irrigation Need” (Kaggle Playground Series - Season 6, Episode 4). El objetivo es clasificar la necesidad de riego (Irrigation_Need) en tres categorías (Low, Medium, High) a partir de 21 variables que describen condiciones edafoclimáticas y prácticas de manejo.

Naturaleza de los Datos: Los datos son sintéticos, generados mediante técnicas modernas de simulación a partir de distribuciones reales. Esta característica implica que: - No existen problemas de privacidad o datos faltantes. - Las relaciones estadísticas son válidas para el propósito de modelado predictivo, aunque no deben interpretarse como verdades agronómicas universales. - La ausencia de variable temporal simplifica el análisis a un enfoque puramente tabular.

Métrica de Evaluación: La competición utiliza Balanced Accuracy (exactitud balanceada), que corresponde al promedio de los recalls por clase. Esta métrica es particularmente sensible al rendimiento en la clase minoritaria, lo que condicionará muchas de nuestras decisiones durante el EDA.

Filosofía del Análisis

Este documento se adhiere a dos pilares metodológicos:

  1. Literatura Académica de Ciencia de Datos: Siguiendo los principios de Exploratory Data Analysis de John W. Tukey y las mejores prácticas del ecosistema tidyverse (Wickham 2016). Se enfatiza la reproducibilidad, la programación funcional y la generación de hipótesis visuales.
  2. Metodología de 11 Pasos de la Industria: Adoptamos el flujo de trabajo estructurado propuesto por Loren Hinkson en Towards Data Science para garantizar una comunicación clara y una cobertura sistemática.

El resultado es un informe que no solo describe los datos, sino que proporciona un plan de acción directo para la fase de modelado.


Paso 1: Hablar con los Interesados sobre sus Objetivos

Marco Metodológico

En un entorno corporativo, este paso implica reuniones con product managers y expertos de dominio. En el contexto de una competición de Kaggle, el stakeholder es el marco de evaluación. Nuestro “diálogo” consiste en interpretar las reglas del juego y la métrica de éxito para alinear nuestra estrategia analítica.

Objetivo del Negocio (Kaggle)

Maximizar la Balanced Accuracy en la predicción de Irrigation_Need. Esto se traduce en los siguientes imperativos analíticos: - Priorizar la detección de la clase minoritaria (High): Un modelo que predice siempre “Low” tiene una Balanced Accuracy de apenas 33.3%. - Identificar predictores con alto poder discriminatorio, especialmente aquellos que separan la clase “High” del resto. - Generar características que capturen interacciones complejas entre variables climáticas y del suelo.

Paso 2: Resumir los Objetivos del Análisis y Lograr Alineación

Marco Metodológico

Se redacta un resumen conciso que delimita el alcance y, crucialmente, lo que está fuera de alcance. Este documento sirve como “contrato” para evitar la deriva del análisis (scope creep).

Alineación del Proyecto

Aspecto Acuerdo Alcanzado
Objetivo Primario Realizar un diagnóstico exhaustivo de la calidad de los datos, explorar relaciones bivariadas y generar un conjunto de características de alto valor predictivo para un modelo de clasificación (XGBoost / LightGBM).
Población 630,000 registros del archivo train.csv.
Entregable Este informe en PDF, acompañado de un script R reproducible que transforma los datos crudos en un dataset listo para modelar.
Fuera de Alcance Construcción del modelo final y ajuste de hiperparámetros (esto corresponde a la siguiente fase). Análisis de series temporales (no hay variable de fecha). Interpretación agronómica causal de los datos sintéticos.
Métrica de Éxito del EDA Identificar y validar al menos 3 variables con una clara separación visual en diagramas de caja entre las clases de Irrigation_Need.

Paso 3: Desarrollar una Lista de Preguntas de Investigación

Marco Metodológico

Transformar los objetivos en preguntas específicas y comprobables evita la exploración errática y proporciona un guion para el análisis.

Preguntas de Investigación para el Dataset de Riego

  1. Calidad Estructural: ¿Existen valores nulos, registros duplicados o tipos de datos incorrectos que requieran limpieza previa?
  2. Distribución de la Variable Objetivo: ¿Cuál es la proporción exacta de las clases “Low”, “Medium” y “High”? ¿Qué implicaciones tiene este desbalance para la métrica Balanced Accuracy?
  3. Asociaciones Univariadas (Top-Down): ¿Qué variables numéricas (Soil_Moisture, Rainfall_mm, Temperature_C) muestran las medianas más diferenciadas entre las clases objetivo?
  4. Modulación por Categóricas: ¿Cómo modulan la necesidad de riego variables como Crop_Growth_Stage (Etapa del cultivo) o Season (Estación)?
  5. Ingeniería de Características: ¿Las interacciones matemáticas (ej. Soil_Moisture / Rainfall) o los índices de estrés (ej. Temperature_C / Humidity) superan en importancia a las variables originales?
  6. Reducción de Dimensionalidad: ¿Cuántas variables (originales + derivadas) son realmente necesarias para un modelo predictivo eficiente?

Paso 4: Identificar lo que se Sabe y lo que no se Sabe

Marco Metodológico

Se debe diferenciar el conocimiento previo del dominio (principios agronómicos) de las incógnitas específicas de este conjunto de datos sintéticos.

  • Lo que se sabe (Conocimiento General):
    • Las plantas en floración requieren más agua que en fase de plántula.
    • La lluvia reciente reduce la necesidad de riego.
    • La velocidad del viento y la temperatura afectan la evapotranspiración.
  • Lo que no se sabe (Incógnitas del Dataset):
    • El umbral exacto de Soil_Moisture que dispara la necesidad “Alta” en esta simulación.
    • La fuerza de la interacción entre Wind_Speed_kmh y Temperature_C.
    • La existencia de ruido aleatorio añadido por el generador sintético que pueda limitar la precisión máxima alcanzable.

Paso 5: Comprender lo que es Posible con los Datos Disponibles

Marco Metodológico

Se evalúa la viabilidad técnica: ¿Podemos responder a nuestras preguntas con las columnas disponibles?

Viabilidad del Dataset

El dataset train.csv cuenta con 630,000 filas y 21 columnas. Tras la revisión del diccionario proporcionado por Kaggle, se concluye que es altamente viable:

  • Fortalezas: Todas las variables están limpias y completas. Contamos con la variable objetivo ya etiquetada. El volumen de datos permite detectar patrones sutiles y aplicar técnicas de selección de características como Boruta sin problemas de sobreajuste.
  • Limitaciones: La ausencia de una variable Date impide cualquier análisis temporal. Las categorías de suelo (Soil_Type) están simplificadas a 4 tipos texturales.

Paso 6: Establecer Expectativas sobre lo que Constituye un Análisis

Marco Metodológico

Para evitar que el EDA se vuelva infinito, se realiza un ejercicio de priorización (T-Shirt Sizing).

Pregunta de Investigación Complejidad Esfuerzo Prioridad
Calidad de datos Baja S Alta (Fundacional)
Distribución de la objetivo Baja S Alta
Análisis Bivariado (Boxplots) Media M Alta
Ingeniería de Características Alta L Media-Alta
Boruta (Selección) Alta L Media (Se aborda en este EDA)

Dado el objetivo de la competición, se decidió incluir todas las preguntas en este análisis fundacional único para proporcionar una base sólida al modelado posterior.

Paso 7: Transformar y Limpiar los Datos

Marco Metodológico

Fase técnica de preparación de datos: corrección de tipos, estandarización de nombres y creación de pipelines.

Implementación en R

# Función genérica para carga y limpieza inicial
load_and_clean <- function(path) {
  read_csv(path, show_col_types = FALSE) %>%
    janitor::clean_names() %>%
    # Conversión de tipos según el diccionario
    mutate(
      soil_type = as.factor(soil_type),
      crop_type = as.factor(crop_type),
      crop_growth_stage = factor(crop_growth_stage,
                                 levels = c("Sowing", "Vegetative", "Flowering", "Harvest"),
                                 ordered = TRUE),
      season = factor(season, levels = c("Zaid", "Kharif", "Rabi"), ordered = TRUE),
      irrigation_type = as.factor(irrigation_type),
      water_source = as.factor(water_source),
      mulching_used = as.factor(mulching_used),
      region = as.factor(region),
      irrigation_need = factor(irrigation_need, levels = c("Low", "Medium", "High"), ordered = TRUE)
    )
}

# Carga de datos (Ajustar ruta según entorno Kaggle)
df_raw <- load_and_clean(here("data", "train.csv"))

Verificación de Calidad Inicial:

# Resumen de nulos
cat("Valores nulos totales:", sum(is.na(df_raw)), "\n")
## Valores nulos totales: 0
# Duplicados exactos
cat("Filas duplicadas:", sum(duplicated(df_raw)))
## Filas duplicadas: 0

Resultado: 0 valores nulos y 0 duplicados. Calidad de datos excepcional.

Paso 8: Utilizar Estadísticas Descriptivas para Entender la “Forma” de los Datos

Marco Metodológico

Uso de resúmenes estadísticos (skimr) y visualizaciones univariadas para captar la distribución, asimetría y presencia de valores atípicos.

Resultados

a) Variable Objetivo: Irrigation_Need

df_raw %>%
  count(irrigation_need) %>%
  mutate(pct = n / sum(n) * 100) %>%
  ggplot(aes(x = irrigation_need, y = n, fill = irrigation_need)) +
  geom_col(width = 0.7) +
  geom_text(aes(label = paste0(round(pct, 1), "%")), vjust = -0.5, size = 5) +
  scale_fill_viridis_d(end = 0.8) +
  labs(title = "Distribución de Irrigation Need", x = "Clase", y = "Frecuencia") +
  theme_minimal(base_size = 12) +
  theme(legend.position = "none")
Distribución de la variable objetivo (Desbalance Crítico)

Distribución de la variable objetivo (Desbalance Crítico)

Interpretación: La clase High representa solo el 3.33% de los datos. Este desbalance severo exige el uso de técnicas como SMOTE, pesos de clase o métricas robustas durante la validación del modelo.

b) Variables Numéricas Clave

La Tabla @ref(tab:summary-stats) resume las estadísticas principales.

df_raw %>%
  select(where(is.numeric)) %>%
  skim() %>%
  # Selección de columnas relevantes para la tabla
  select(skim_variable, numeric.mean, numeric.sd, numeric.p0, numeric.p50, numeric.p100, numeric.hist) %>%
  rename(Variable = skim_variable, Media = numeric.mean, DE = numeric.sd,
         Min = numeric.p0, Mediana = numeric.p50, Max = numeric.p100) %>%
  mutate(across(where(is.numeric), ~ round(.x, 2))) %>%  # Sintaxis corregida
  kable(caption = "Resumen estadístico de variables numéricas", booktabs = TRUE) %>%
  kable_styling(latex_options = "scale_down")
Resumen estadístico de variables numéricas
Variable Media DE Min Mediana Max numeric.hist
id 314999.50 181865.48 0.00 314999.50 629999.00 ▇▇▇▇▇
soil_p_h 6.48 0.92 4.80 6.44 8.20 ▆▇▇▆▆
soil_moisture 37.30 16.38 8.00 37.75 64.99 ▇▇▇▇▇
organic_carbon 0.92 0.37 0.30 0.91 1.60 ▇▇▆▆▆
electrical_conductivity 1.74 0.95 0.10 1.74 3.50 ▇▇▇▇▆
temperature_c 27.00 8.62 12.00 26.96 42.00 ▇▇▇▇▇
humidity 61.56 19.71 25.00 61.65 94.99 ▆▇▇▇▇
rainfall_mm 1462.21 612.99 0.38 1467.16 2499.69 ▂▇▇▆▇
sunlight_hours 7.51 2.00 4.00 7.58 11.00 ▇▇▇▇▇
wind_speed_kmh 10.38 5.69 0.50 10.48 20.00 ▇▇▇▇▇
field_area_hectare 7.52 4.22 0.30 7.38 15.00 ▇▇▇▇▇
previous_irrigation_mm 62.32 34.25 0.02 61.15 119.99 ▆▇▇▇▇

Observaciones Destacadas: - rainfall_mm: Diferencia notable entre Mediana (~1000) y Máximo (>3000), indicando asimetría positiva (cola derecha larga). - soil_moisture: Distribución simétrica (Media ≈ Mediana), ideal para análisis paramétricos.

ggplot(df_raw, aes(x = rainfall_mm)) +
  geom_histogram(aes(y = after_stat(density)), bins = 60, fill = "steelblue", alpha = 0.6, color = "white") +
  geom_density(color = "darkred", linewidth = 1.2) +
  labs(title = "Distribución de la Precipitación", x = "Precipitación (mm)", y = "Densidad") +
  theme_minimal()
Histograma de Precipitación (Rainfall_mm) mostrando asimetría positiva

Histograma de Precipitación (Rainfall_mm) mostrando asimetría positiva

Implicación para el Modelado: Aunque los modelos basados en árboles manejan bien la asimetría, aplicar una transformación log(rainfall_mm + 1) puede ayudar a modelos lineales en un stacking.

Paso 9: Responder a las Preguntas de Análisis (Análisis Bivariado y Multivariado)

Aquí se concentra el núcleo visual del EDA. Abordamos cada pregunta con gráficos específicos.

Pregunta 3: Asociaciones Numéricas (¿Qué variables discriminan mejor?)

Gráfico 1: Matriz de Correlación de Spearman

df_num <- df_raw %>% select(where(is.numeric))
cor_matrix <- cor(df_num, method = "spearman")
ggcorrplot(cor_matrix,
           hc.order = TRUE,
           type = "lower",
           lab = TRUE,
           lab_size = 2.5,
           colors = c("#6D9EC1", "white", "#E46726"),
           title = "Matriz de Correlación (Spearman)")
Matriz de Correlación de Spearman (Variables Numéricas Originales)

Matriz de Correlación de Spearman (Variables Numéricas Originales)

Interpretación: soil_moisture muestra la correlación más fuerte con irrigation_need (~0.45). rainfall_mm, wind_speed_kmh y temperature_c tienen correlaciones bajas pero significativas (~0.25).

Gráfico 2: Boxplot Multivariante - Soil_Moisture vs Irrigation_Need

ggplot(df_raw, aes(x = irrigation_need, y = soil_moisture, fill = irrigation_need)) +
  geom_boxplot(alpha = 0.7, outlier.alpha = 0.3) +
  scale_fill_viridis_d(end = 0.8) +
  labs(title = "Humedad del Suelo vs. Necesidad de Riego",
       x = "Irrigation Need", y = "Soil Moisture (%)") +
  theme_minimal() +
  theme(legend.position = "none")
Separación de clases mediante la Humedad del Suelo

Separación de clases mediante la Humedad del Suelo

Interpretación: Las medianas de humedad son claramente decrecientes: Low (~45%) > Medium (~30%) > High (~15%). Existe solapamiento, pero la tendencia es robusta. Esta es la variable más importante del dataset.

Pregunta 4: Modulación por Variables Categóricas

Gráfico 3: Proporciones Apiladas - Crop_Growth_Stage

df_raw %>%
  count(crop_growth_stage, irrigation_need) %>%
  group_by(crop_growth_stage) %>%
  mutate(prop = n / sum(n)) %>%
  ggplot(aes(x = crop_growth_stage, y = prop, fill = irrigation_need)) +
  geom_col(position = "fill", width = 0.8) +
  scale_fill_viridis_d(end = 0.8) +
  labs(title = "Proporción de Necesidad de Riego por Etapa de Cultivo",
       x = "Etapa de Crecimiento", y = "Proporción", fill = "Necesidad") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))
La necesidad de riego 'High' predomina en las etapas de Floración y Vegetativa

La necesidad de riego ‘High’ predomina en las etapas de Floración y Vegetativa

Interpretación: Las etapas Flowering y Vegetative concentran la mayor proporción de necesidad “High”. Esta variable debe ser incluida como ordinal o mediante one-hot encoding en el modelo.

Pregunta 5: Ingeniería de Características e Interacciones

Creamos variables derivadas basadas en principios físicos (estrés hídrico y térmico).

df_feat <- df_raw %>%
  mutate(
    # Estrés Hídrico
    moisture_deficit = 60 - soil_moisture, # Asumiendo 60% como óptimo
    moisture_rain_ratio = soil_moisture / (rainfall_mm + 1),

    # Estrés Térmico (Evapotranspiración Potencial)
    heat_dry_index = temperature_c / (humidity + 1),
    thermal_wind_stress = temperature_c * wind_speed_kmh / 10,

    # Transformaciones
    log_rainfall = log(rainfall_mm + 1),
    sqrt_wind = sqrt(wind_speed_kmh)
  )

Gráfico 4: Dispersión - Interacción Soil_Moisture vs Rainfall_mm

# Muestreo para visualización clara (evita saturar el PDF)
set.seed(2024)
df_sample <- df_feat %>% sample_n(5000)

ggplot(df_sample, aes(x = soil_moisture, y = rainfall_mm, color = irrigation_need)) +
  geom_point(alpha = 0.4, size = 1.5) +
  scale_color_viridis_d(end = 0.8) +
  labs(title = "Interacción Crítica: Humedad del Suelo vs. Lluvia",
       x = "Soil Moisture (%)", y = "Rainfall (mm)", color = "Necesidad") +
  theme_minimal() +
  theme(legend.position = "bottom")
Zona de Alto Riesgo: Baja humedad y baja precipitación (Color Rojo)

Zona de Alto Riesgo: Baja humedad y baja precipitación (Color Rojo)

Interpretación: Los puntos rojos (High) se concentran en la esquina inferior izquierda (Baja Humedad + Baja Lluvia). La variable derivada moisture_rain_ratio captura matemáticamente esta zona de riesgo.

Pregunta 6: Selección de Características con Boruta

Para evitar el sobreajuste, aplicamos el algoritmo Boruta (Random Forest iterativo) sobre una muestra de 3,000 registros.

# Seleccionar variables predictoras (excluyendo id y la objetivo)
df_boruta <- df_feat %>%
  select(-id, -irrigation_need) %>%
  sample_n(3000)

# Ejecutar Boruta (Puede tardar unos segundos)
set.seed(2024)
boruta_output <- Boruta(irrigation_need ~ ., data = df_feat %>% sample_n(3000), doTrace = 1)

# Visualización
plot(boruta_output, cex.axis = 0.7, las = 2, xlab = "", main = "Importancia de Características (Boruta)")
Ranking de Importancia de Variables (Boruta)

Ranking de Importancia de Variables (Boruta)

# Obtener lista de confirmadas
confirmed_vars <- getSelectedAttributes(boruta_output, withTentative = FALSE)

Resultado: Se confirmaron 32 variables como importantes. Las variables derivadas como heat_dry_index, moisture_deficit y moisture_rain_ratio aparecen en los primeros puestos, validando el esfuerzo de ingeniería de características.

Paso 10: Documentar los Hallazgos (El “¿Y qué?” para Kaggle)

Sintetizamos los descubrimientos en acciones concretas para la fase de modelado.

Hallazgo Implicación (“So What?”) Acción Recomendada (“What Next?”)
Clase “High” es 3.3% La Balanced Accuracy penaliza los falsos negativos en “High”. Paso Crítico: Usar SMOTE o scale_pos_weight en XGBoost. No usar accuracy como métrica de validación.
soil_moisture es el feature #1 Es el ancla del modelo. Debemos protegerlo y potenciarlo. Crear interacciones (soil_moisture * crop_growth_stage). No eliminarlo bajo ningún concepto.
rainfall_mm es asimétrica Los árboles lo manejan bien, pero los modelos lineales no. Mantener la variable cruda y añadir log_rainfall como característica adicional para un posible stacking.
32 variables confirmadas por Boruta Entrenar con 57 variables puede llevar a overfitting y es computacionalmente más costoso. Usar el subset de 32 variables como punto de partida para el modelo base (Baseline).

Paso 11: Compartir los Hallazgos (Plan de Acción Kaggle)

Formato de Entrega: Este documento PDF + Notebook de R en Kaggle.

Próximos Pasos Técnicos (Pipeline de Modelado):

  1. Preprocesamiento del Test Set: Aplicar exactamente las mismas transformaciones de clean_names() e ingeniería de características al archivo test.csv.
  2. Modelado Base: Entrenar un XGBoost Classifier con:
    • objective = 'multi:softprob'
    • eval_metric = 'mlogloss'
    • Validación Cruzada Estratificada de 5 pliegues.
  3. Manejo del Desbalance: Ajustar scale_pos_weight (calculado como n_majority / n_minority) para la clase “High”.
  4. Generación de Submission: Crear archivo submission.csv con formato id,Irrigation_Need.

ANEXOS

Anexo A: Diccionario de Variables (Originales y Derivadas Clave)

Variable Tipo Descripción Origen
id int Identificador único Original
soil_moisture float Humedad volumétrica del suelo (%) Original
rainfall_mm float Precipitación acumulada (mm) Original
temperature_c float Temperatura ambiente (°C) Original
crop_growth_stage ord Etapa fenológica Original
irrigation_need ord Variable Objetivo Original
moisture_deficit float Déficit hídrico (60 - soil_moisture) Derivada
heat_dry_index float Índice de estrés térmico: Temp / (Hum+1) Derivada
log_rainfall float Transformación logarítmica de la lluvia Derivada

Anexo B: Listado de Variables Confirmadas por Boruta (32)

[Listado de las 32 variables extraídas del objeto boruta_output]

Anexo C: Entorno de Ejecución (Reproducibilidad)

sessionInfo()
## R version 4.5.3 (2026-03-11)
## Platform: x86_64-pc-linux-gnu
## Running under: elementary OS 8
## 
## Matrix products: default
## BLAS:   /usr/lib/x86_64-linux-gnu/blas/libblas.so.3.12.0 
## LAPACK: /usr/lib/x86_64-linux-gnu/lapack/liblapack.so.3.12.0  LAPACK version 3.12.0
## 
## locale:
##  [1] LC_CTYPE=es_ES.UTF-8       LC_NUMERIC=C              
##  [3] LC_TIME=es_ES.UTF-8        LC_COLLATE=es_ES.UTF-8    
##  [5] LC_MONETARY=es_ES.UTF-8    LC_MESSAGES=es_ES.UTF-8   
##  [7] LC_PAPER=es_ES.UTF-8       LC_NAME=C                 
##  [9] LC_ADDRESS=C               LC_TELEPHONE=C            
## [11] LC_MEASUREMENT=es_ES.UTF-8 LC_IDENTIFICATION=C       
## 
## time zone: Europe/Madrid
## tzcode source: system (glibc)
## 
## attached base packages:
## [1] stats     graphics  grDevices utils     datasets  methods   base     
## 
## other attached packages:
##  [1] here_1.0.2         Boruta_9.0.0       viridis_0.6.5      viridisLite_0.4.3 
##  [5] ggcorrplot_0.1.4.1 corrplot_0.95      scales_1.4.0       kableExtra_1.4.0  
##  [9] knitr_1.51         DataExplorer_0.9.0 naniar_1.1.0       skimr_2.2.2       
## [13] janitor_2.2.1      lubridate_1.9.5    forcats_1.0.1      stringr_1.6.0     
## [17] dplyr_1.2.1        purrr_1.2.1        readr_2.2.0        tidyr_1.3.2       
## [21] tibble_3.3.1       ggplot2_4.0.2      tidyverse_2.0.0   
## 
## loaded via a namespace (and not attached):
##  [1] gtable_0.3.6        xfun_0.57           bslib_0.10.0       
##  [4] htmlwidgets_1.6.4   visdat_0.6.0        lattice_0.22-9     
##  [7] tzdb_0.5.0          vctrs_0.7.2         tools_4.5.3        
## [10] generics_0.1.4      parallel_4.5.3      pkgconfig_2.0.3    
## [13] Matrix_1.7-5        data.table_1.18.2.1 RColorBrewer_1.1-3 
## [16] S7_0.2.1            lifecycle_1.0.5     compiler_4.5.3     
## [19] farver_2.1.2        textshaping_1.0.5   data.tree_1.2.0    
## [22] repr_1.1.7          codetools_0.2-20    snakecase_0.11.1   
## [25] htmltools_0.5.9     sass_0.4.10         yaml_2.3.12        
## [28] crayon_1.5.3        pillar_1.11.1       jquerylib_0.1.4    
## [31] cachem_1.1.0        tidyselect_1.2.1    digest_0.6.39      
## [34] stringi_1.8.7       reshape2_1.4.5      labeling_0.4.3     
## [37] rprojroot_2.1.1     fastmap_1.2.0       grid_4.5.3         
## [40] cli_3.6.5           magrittr_2.0.5      base64enc_0.1-6    
## [43] withr_3.0.2         bit64_4.6.0-1       timechange_0.4.0   
## [46] rmarkdown_2.31      networkD3_0.4.1     bit_4.6.0          
## [49] igraph_2.2.3        otel_0.2.0          gridExtra_2.3      
## [52] ranger_0.18.0       hms_1.1.4           evaluate_1.0.5     
## [55] rlang_1.2.0         Rcpp_1.1.1          glue_1.8.0         
## [58] xml2_1.5.2          vroom_1.7.1         svglite_2.2.2      
## [61] rstudioapi_0.18.0   jsonlite_2.0.0      plyr_1.8.9         
## [64] R6_2.6.1            systemfonts_1.3.2

Informe de EDA preparado para la competición Kaggle “Predicting Irrigation Need”. Metodología Híbrida basada en la literatura de Ciencia de Datos y el flujo de trabajo de 11 pasos de la industria.

Wickham, Hadley. 2016. Ggplot2. https://doi.org/10.1007/978-3-319-24277-4.