# Instalar y cargar paquetes si es necesario
# install.packages("tidyverse")
library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.2.1     ✔ readr     2.2.0
## ✔ forcats   1.0.1     ✔ stringr   1.6.0
## ✔ ggplot2   4.0.3     ✔ tibble    3.3.1
## ✔ lubridate 1.9.5     ✔ tidyr     1.3.2
## ✔ purrr     1.2.2     
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors

Establecer semilla para reproducibilidad

set.seed(42)

Simular datos similares a los de Python

df_lotes_r <- tibble( ID_Parcela = 1:200, Zona = sample(c(‘Norte’, ‘Sur’, ‘Este’, ‘Oeste’), 200, replace = TRUE), Textura_Suelo = sample(c(‘Arcilloso’, ‘Franco’, ‘Arenoso’), 200, replace = TRUE, prob = c(0.3, 0.5, 0.2)) ) %>% mutate( Humedad_base = case_when( Textura_Suelo == ‘Arcilloso’ ~ 30, Textura_Suelo == ‘Franco’ ~ 22, TRUE ~ 12 ), Humedad_ = Humedad_base + rnorm(200, mean = 0, sd = 3), Rendimiento_ton_ha = 3 + (Humedad_ * 0.15) + if_else(Textura_Suelo == ‘Franco’, 2.5, 0) + rnorm(200, mean = 0, sd = 1.5) ) %>% select(-Humedad_base)

Mostrar las primeras filas

print(head(df_lotes_r))

Instalar y cargar paquetes si es necesario

install.packages(“tidyverse”)

library(tidyverse)

Establecer semilla para reproducibilidad

set.seed(42)

Simular datos similares a los de Python

df_lotes_r <- tibble( ID_Parcela = 1:200, Zona = sample(c(‘Norte’, ‘Sur’, ‘Este’, ‘Oeste’), 200, replace = TRUE), Textura_Suelo = sample(c(‘Arcilloso’, ‘Franco’, ‘Arenoso’), 200, replace = TRUE, prob = c(0.3, 0.5, 0.2)) ) %>% mutate( Humedad_base = case_when( Textura_Suelo == ‘Arcilloso’ ~ 30, Textura_Suelo == ‘Franco’ ~ 22, TRUE ~ 12 ), Humedad_ = Humedad_base + rnorm(200, mean = 0, sd = 3), Rendimiento_ton_ha = 3 + (Humedad_ * 0.15) + if_else(Textura_Suelo == ‘Franco’, 2.5, 0) + rnorm(200, mean = 0, sd = 1.5) ) %>% select(-Humedad_base)

Mostrar las primeras filas

print(head(df_lotes_r)) # 1. Resúmenes Estadísticos Agrupados con dplyr resumen_suelos_r <- df_lotes_r %>% group_by(Textura_Suelo) %>% summarise( Humedad_media = mean(Humedad_, na.rm = TRUE), Rendimiento_medio = mean(Rendimiento_ton_ha, na.rm = TRUE) )

print(resumen_suelos_r)

2. Comparación Visual de Grupos (Boxplots Categóricos)

df_lotes_r %>% ggplot(aes(x = Textura_Suelo, y = Rendimiento_ton_ha, fill = Textura_Suelo)) + geom_boxplot() + labs(title = ‘Variabilidad del Rendimiento según el Tipo de Suelo’, x = ‘Textura del Suelo’, y = ‘Rendimiento (ton/ha)’) + theme_minimal() + scale_fill_viridis_d(option = “A”, begin = 0.5)

3. Análisis Multivariado con Facetas (ggplot2)

df_lotes_r %>% ggplot(aes(x = Humedad_, y = Rendimiento_ton_ha, color = Textura_Suelo)) + geom_point(alpha = 0.7) + geom_smooth(method = “lm”, se = FALSE) + facet_wrap(~ Zona, ncol = 2) + # Facetas por Zona, 2 columnas labs(title = ‘Relación Humedad-Rendimiento por Zona y Tipo de Suelo’, x = ‘Humedad (%)’, y = ‘Rendimiento (ton/ha)’, color = ‘Textura del Suelo’) + theme_minimal() + scale_color_viridis_d(option = “D”)



A continuación se explica el código línea por línea, tanto desde el punto de vista de **R** como de su interpretación en **estadística aplicada a la ingeniería agrícola**.

## 1. Instalación y carga de paquetes

```r
# Instalar y cargar paquetes si es necesario
# install.packages("tidyverse")
library(tidyverse)

tidyverse incluye herramientas importantes como:

En estadística agrícola, estas herramientas permiten organizar datos de parcelas, resumir variables de suelo y analizar visualmente el rendimiento.


2. Establecer una semilla

# Establecer semilla para reproducibilidad
set.seed(42)
  • set.seed(42): fija la semilla del generador de números aleatorios.

El código utiliza posteriormente:

  • sample(), para seleccionar categorías aleatoriamente.
  • rnorm(), para generar errores aleatorios con distribución normal.

La semilla garantiza que, al ejecutar nuevamente el código, se obtengan los mismos datos simulados.

Interpretación agrícola

Esto es importante para que un análisis sea:

  • reproducible;
  • verificable;
  • comparable entre investigadores;
  • útil para probar métodos estadísticos antes de utilizar datos reales.

La semilla 42 es arbitraria. El valor no tiene un significado estadístico especial.


3. Crear la tabla de datos

df_lotes_r <- tibble(
  • df_lotes_r <-: crea un objeto llamado df_lotes_r.
  • <- es el operador de asignación en R.
  • tibble() crea una tabla de datos.

El nombre puede interpretarse como:

  • df: data frame o tabla de datos;
  • lotes: parcelas o lotes agrícolas;
  • _r: versión elaborada en R.

Identificador de parcela

  ID_Parcela = 1:200,
  • 1:200 genera la secuencia de números enteros del 1 al 200.
  • Cada parcela recibe un identificador único.

Interpretación agrícola

Se simulan 200 lotes o parcelas experimentales. El identificador no es una variable productiva; solo sirve para distinguir cada observación.


Zona geográfica

  Zona = sample(c('Norte', 'Sur', 'Este', 'Oeste'), 200, replace = TRUE),
  • c(...) combina las cuatro categorías posibles.
  • sample(...) selecciona aleatoriamente una categoría.
  • 200 indica que se generan 200 valores.
  • replace = TRUE permite que una misma zona sea seleccionada varias veces.

Cada parcela se asigna aleatoriamente a una de las cuatro zonas:

  • Norte;
  • Sur;
  • Este;
  • Oeste.

Interpretación estadística

Zona es una variable cualitativa nominal. No existe un orden natural entre Norte, Sur, Este y Oeste.

Interpretación agrícola

La zona puede representar diferentes sectores del campo, condiciones topográficas, regiones climáticas o unidades de manejo.


Textura del suelo

  Textura_Suelo = sample(
    c('Arcilloso', 'Franco', 'Arenoso'),
    200,
    replace = TRUE,
    prob = c(0.3, 0.5, 0.2)
  )
  • Se generan 200 observaciones.
  • Las categorías posibles son:
    • Arcilloso;
    • Franco;
    • Arenoso.
  • prob = c(0.3, 0.5, 0.2) establece las probabilidades de selección:
Textura Probabilidad esperada
Arcilloso 30 %
Franco 50 %
Arenoso 20 %

Estas son probabilidades teóricas. En una muestra concreta, los porcentajes observados pueden ser ligeramente diferentes.

Interpretación agrícola

La textura del suelo afecta propiedades como:

  • retención de agua;
  • drenaje;
  • aireación;
  • disponibilidad de nutrientes;
  • facilidad de laboreo;
  • respuesta del cultivo al riego.

Es una variable categórica nominal.


4. Crear variables mediante mutate()

) %>%
  mutate(
  • ) cierra la creación inicial del tibble.
  • %>% es el operador pipe. Pasa el resultado de una operación a la siguiente.
  • mutate() crea nuevas columnas o modifica columnas existentes.

En este caso, se calculan:

  • humedad base;
  • humedad observada;
  • rendimiento.

5. Humedad base según la textura

    Humedad_base = case_when(
      Textura_Suelo == 'Arcilloso' ~ 30,
      Textura_Suelo == 'Franco' ~ 22,
      TRUE ~ 12
    ),

case_when() permite establecer condiciones múltiples.

La lógica es:

  • si el suelo es arcilloso, la humedad base es 30;
  • si el suelo es franco, la humedad base es 22;
  • para cualquier otro caso, la humedad base es 12.

TRUE ~ 12 funciona como condición final. En este caso, corresponde al suelo arenoso.

Interpretación estadística

Se está definiendo una relación determinista entre la textura y el nivel medio de humedad:

Textura Humedad base
Arcilloso 30
Franco 22
Arenoso 12

Interpretación agrícola

La lógica representa que:

  • el suelo arcilloso retiene más agua;
  • el suelo franco presenta una retención intermedia;
  • el suelo arenoso retiene menos agua.

Los valores pueden interpretarse como porcentajes de humedad, aunque en datos reales habría que especificar si se trata de humedad gravimétrica, volumétrica u otra unidad.


6. Generar la humedad observada

    Humedad_ = Humedad_base + rnorm(200, mean = 0, sd = 3),
  • rnorm(200, mean = 0, sd = 3) genera 200 valores aleatorios de una distribución normal.
  • mean = 0: el error promedio es cero.
  • sd = 3: la desviación estándar del error es 3.
  • Cada valor se suma a Humedad_base.

Matemáticamente, la variable simulada sigue aproximadamente:

Humedad observada = Humedad base + error aleatorio

Interpretación estadística

La humedad no es exactamente igual para todas las parcelas con la misma textura. Existe variabilidad natural alrededor de la media.

Por ejemplo, para un suelo franco:

Humedad_ ≈ 22 ± variación aleatoria

La desviación estándar de 3 representa heterogeneidad entre parcelas, error de medición o factores no incluidos en el modelo.

Interpretación agrícola

Aunque dos parcelas tengan la misma textura, pueden diferir en humedad debido a:

  • lluvia;
  • frecuencia de riego;
  • pendiente;
  • compactación;
  • materia orgánica;
  • cobertura vegetal;
  • profundidad efectiva;
  • drenaje.

El nombre Humedad_ termina en guion bajo, pero es válido en R. Un nombre más descriptivo podría ser:

Humedad_porcentaje

7. Simular el rendimiento

    Rendimiento_ton_ha = 3 + (Humedad_ * 0.15) +
      if_else(Textura_Suelo == 'Franco', 2.5, 0) +
      rnorm(200, mean = 0, sd = 1.5)

Esta expresión construye el rendimiento mediante varios componentes:

Rendimiento =
  3
  + efecto de la humedad
  + efecto adicional del suelo franco
  + error aleatorio

Intercepto

3

Es el nivel inicial o intercepto del modelo.

Representa un rendimiento base de 3 toneladas por hectárea antes de considerar la humedad, el tipo de suelo y el error aleatorio.


Efecto de la humedad

(Humedad_ * 0.15)

Por cada unidad adicional de humedad, el rendimiento aumenta, en promedio, en:

0.15 ton/ha

Por ejemplo, una diferencia de 10 unidades de humedad se asociaría con:

10 × 0.15 = 1.5 ton/ha

Interpretación agrícola

El modelo supone una relación lineal positiva entre humedad y rendimiento. En términos prácticos, una mayor disponibilidad de agua favorece el crecimiento del cultivo, dentro del rango considerado.

Sin embargo, en la realidad esta relación podría no ser indefinidamente creciente. Un exceso de humedad puede provocar:

  • falta de oxígeno en las raíces;
  • enfermedades;
  • lixiviación de nutrientes;
  • problemas de drenaje.

Por eso, para datos reales, puede ser necesario utilizar modelos no lineales.


Efecto adicional del suelo franco

if_else(Textura_Suelo == 'Franco', 2.5, 0)

if_else() asigna:

  • 2.5 si el suelo es franco;
  • 0 para las demás texturas.

Por tanto, el suelo franco recibe un incremento adicional de 2.5 ton/ha.

Interpretación estadística

Esta variable representa un efecto categórico codificado manualmente. El modelo está suponiendo que, manteniendo constante la humedad, el suelo franco tiene una ventaja adicional de 2.5 ton/ha.

Interpretación agrícola

El suelo franco suele tener un equilibrio favorable entre:

  • retención de humedad;
  • drenaje;
  • aireación;
  • disponibilidad de nutrientes;
  • facilidad de desarrollo radicular.

No obstante, el valor de 2.5 es supuesto para la simulación, no una estimación proveniente de datos reales.


Error aleatorio del rendimiento

rnorm(200, mean = 0, sd = 1.5)

Se agrega variabilidad aleatoria con:

  • media 0;
  • desviación estándar 1.5 ton/ha.

Interpretación agrícola

El error puede representar factores no incluidos, como:

  • variedad sembrada;
  • fecha de siembra;
  • fertilización;
  • plagas y enfermedades;
  • manejo del riego;
  • radiación solar;
  • temperatura;
  • errores de medición;
  • diferencias entre productores.

8. Eliminar la humedad base

  ) %>%
  select(-Humedad_base)
  • select() selecciona columnas.
  • -Humedad_base indica que esa columna debe eliminarse.

La columna se utilizó como variable intermedia, pero se elimina de la tabla final porque ya no es necesaria.

La tabla conserva:

  • ID_Parcela;
  • Zona;
  • Textura_Suelo;
  • Humedad_;
  • Rendimiento_ton_ha.

Interpretación estadística

Eliminar variables auxiliares ayuda a mantener una base limpia y evita confundir:

  • humedad base teórica;
  • humedad observada.

9. Mostrar las primeras filas

# Mostrar las primeras filas
print(head(df_lotes_r))
  • head(df_lotes_r) muestra normalmente las primeras seis filas.
  • print() imprime el resultado en la consola.

Esto permite comprobar:

  • que la tabla fue creada;
  • que las columnas tienen los nombres esperados;
  • que los valores parecen razonables;
  • que no existen errores evidentes.

1. Resúmenes estadísticos agrupados

resumen_suelos_r <- df_lotes_r %>%
  group_by(Textura_Suelo) %>%
  summarise(
    Humedad_media = mean(Humedad_, na.rm = TRUE),
    Rendimiento_medio = mean(Rendimiento_ton_ha, na.rm = TRUE)
  )

Agrupar por textura

group_by(Textura_Suelo)

Divide las observaciones en grupos según:

  • Arcilloso;
  • Franco;
  • Arenoso.

Interpretación agrícola

Permite comparar el comportamiento de las parcelas según el tipo de suelo.


Calcular humedad media

Humedad_media = mean(Humedad_, na.rm = TRUE)
  • mean() calcula la media aritmética.
  • na.rm = TRUE indica que se ignoren los valores ausentes, si existen.

La media de humedad para cada textura se calcula como:

Suma de humedades del grupo / número de parcelas del grupo

Interpretación

Permite estimar la humedad promedio asociada a cada textura.

Se espera aproximadamente que:

  • los suelos arcillosos tengan la mayor humedad media;
  • los suelos francos tengan una humedad intermedia;
  • los suelos arenosos tengan la menor humedad media.

Calcular rendimiento medio

Rendimiento_medio = mean(Rendimiento_ton_ha, na.rm = TRUE)

Calcula el rendimiento promedio de cada tipo de suelo.

Interpretación agrícola

Permite responder preguntas como:

  • ¿Qué textura produce más en promedio?
  • ¿El suelo franco presenta mayor rendimiento?
  • ¿La diferencia observada parece agronómicamente importante?

Es importante distinguir entre:

  • diferencia descriptiva: la media de un grupo es mayor;
  • diferencia estadísticamente significativa: la diferencia ha sido evaluada con una prueba formal;
  • diferencia agronómicamente relevante: la diferencia tiene importancia práctica para la producción.

Este código solo realiza estadística descriptiva. No prueba significancia estadística.


Mostrar el resumen

print(resumen_suelos_r)

Imprime la tabla de medias agrupadas.

Un resumen más completo podría incluir también:

n = n(),
desviacion = sd(Rendimiento_ton_ha, na.rm = TRUE)

La desviación estándar permitiría conocer la variabilidad dentro de cada textura.


2. Comparación visual mediante diagramas de caja

df_lotes_r %>%
  ggplot(aes(
    x = Textura_Suelo,
    y = Rendimiento_ton_ha,
    fill = Textura_Suelo
  )) +

Crear el gráfico

  • ggplot() inicia un gráfico.
  • aes() define las asociaciones entre variables y elementos gráficos.

En este caso:

  • x = Textura_Suelo: la textura aparece en el eje horizontal.
  • y = Rendimiento_ton_ha: el rendimiento aparece en el eje vertical.
  • fill = Textura_Suelo: cada textura tendrá un color diferente.

Añadir diagramas de caja

  geom_boxplot() +

geom_boxplot() crea un diagrama de caja para cada categoría.

Un boxplot muestra:

  • mediana;
  • primer cuartil;
  • tercer cuartil;
  • rango intercuartílico;
  • valores potencialmente atípicos.

Interpretación estadística

La caja contiene aproximadamente el 50 % central de los datos.

  • Una caja más alta indica mayor variabilidad central.
  • Una línea de mediana más alta indica un rendimiento central mayor.
  • Puntos alejados pueden representar observaciones atípicas.

Interpretación agrícola

El gráfico permite comparar no solo el rendimiento promedio, sino también su estabilidad.

Por ejemplo, un tipo de suelo puede tener:

  • rendimiento promedio alto, pero gran variabilidad;
  • rendimiento ligeramente menor, pero más estable;
  • valores extremos debido a manejo, plagas o condiciones particulares.

Títulos y etiquetas

  labs(
    title = 'Variabilidad del Rendimiento según el Tipo de Suelo',
    x = 'Textura del Suelo',
    y = 'Rendimiento (ton/ha)'
  ) +

labs() modifica:

  • título;
  • etiqueta del eje X;
  • etiqueta del eje Y.

Las unidades ton/ha indican toneladas por hectárea.


Tema visual

  theme_minimal() +

Aplica un diseño visual sencillo con pocos elementos decorativos.

Esto facilita la lectura de las diferencias entre grupos.


Escala de colores

  scale_fill_viridis_d(option = "A", begin = 0.5)
  • scale_fill_viridis_d() utiliza una paleta de colores adecuada para variables discretas.
  • option = "A" selecciona una variante de la paleta.
  • begin = 0.5 comienza la paleta desde una parte intermedia.

Estas paletas suelen ser útiles porque presentan buen contraste y son relativamente accesibles para personas con dificultades para distinguir ciertos colores.


3. Análisis multivariado con facetas

df_lotes_r %>%
  ggplot(aes(
    x = Humedad_,
    y = Rendimiento_ton_ha,
    color = Textura_Suelo
  )) +

Se crea un gráfico de dispersión donde:

Cada punto representa una parcela.

Interpretación agrícola

Este gráfico permite estudiar simultáneamente:

  1. la relación entre humedad y rendimiento;
  2. las diferencias entre texturas;
  3. la distribución de las parcelas;
  4. posibles observaciones atípicas.

Puntos de dispersión

  geom_point(alpha = 0.7) +
  • geom_point() dibuja los puntos.
  • alpha = 0.7 establece una transparencia del 70 % aproximadamente.

La transparencia ayuda a observar zonas donde varios puntos están superpuestos.

Interpretación estadística

La nube de puntos permite evaluar visualmente:

  • dirección de la relación;
  • fuerza aproximada;
  • linealidad;
  • dispersión;
  • diferencias entre grupos.

Líneas de regresión

  geom_smooth(method = "lm", se = FALSE) +
  • geom_smooth() añade una línea suavizada o de tendencia.
  • method = "lm" utiliza un modelo lineal.
  • se = FALSE oculta la banda de confianza.

Como el color está asociado a Textura_Suelo, se ajusta una línea separada para cada textura, dentro de cada zona.

En términos generales, para cada grupo se ajusta:

Rendimiento = intercepto + pendiente × Humedad + error

Interpretación estadística

La pendiente indica cuánto cambia el rendimiento esperado cuando aumenta una unidad la humedad.

  • Pendiente positiva: mayor humedad se asocia con mayor rendimiento.
  • Pendiente cercana a cero: poca relación lineal.
  • Pendiente negativa: mayor humedad se asocia con menor rendimiento.

La línea no demuestra causalidad por sí sola. Solo muestra una asociación lineal en estos datos simulados.

Importante

Al ocultar la banda de confianza con se = FALSE, el gráfico no muestra la incertidumbre de la estimación. Para visualizarla se puede utilizar:

geom_smooth(method = "lm", se = TRUE)

Crear facetas por zona

  facet_wrap(~ Zona, ncol = 2) +
  • facet_wrap(~ Zona) crea un panel separado para cada zona.
  • ncol = 2 organiza los paneles en dos columnas.
  • ~ Zona indica que las facetas se construyen usando la variable Zona.

Se obtienen cuatro paneles:

  • Norte;
  • Sur;
  • Este;
  • Oeste.

Interpretación agrícola

Permite verificar si la relación entre humedad y rendimiento cambia según la zona.

Por ejemplo, una zona podría mostrar menor rendimiento debido a:

  • menor fertilidad;
  • problemas de drenaje;
  • mayor pendiente;
  • menor precipitación;
  • diferencias de manejo;
  • microclima desfavorable.

En la simulación, sin embargo, la zona no se utiliza directamente para calcular el rendimiento. Por ello, cualquier diferencia entre zonas se debe principalmente al azar y a la composición de texturas de cada zona.


Etiquetas del gráfico

  labs(
    title = 'Relación Humedad-Rendimiento por Zona y Tipo de Suelo',
    x = 'Humedad (%)',
    y = 'Rendimiento (ton/ha)',
    color = 'Textura del Suelo'
  ) +

Se asignan:

  • título general;
  • nombre del eje horizontal;
  • nombre del eje vertical;
  • título de la leyenda de colores.

El título indica que se estudian simultáneamente:

  • humedad;
  • rendimiento;
  • zona;
  • textura del suelo.

Tema y escala de colores

  theme_minimal() +
  scale_color_viridis_d(option = "D")
  • theme_minimal() aplica un estilo limpio.
  • scale_color_viridis_d() asigna colores a las categorías de textura.
  • option = "D" utiliza otra variante de la paleta Viridis.

Aquí se utiliza color, porque se colorean los puntos y las líneas, mientras que en el boxplot se usó fill, porque se rellenaban las cajas.


Interpretación general del análisis

El código simula una situación agrícola en la que:

  1. Se observan 200 parcelas.
  2. Cada parcela pertenece a una zona.
  3. Cada parcela tiene una textura de suelo.
  4. La textura influye en la humedad base.
  5. La humedad observada presenta variabilidad natural.
  6. El rendimiento aumenta con la humedad.
  7. El suelo franco recibe un efecto adicional positivo.
  8. El rendimiento también presenta variación aleatoria.

El modelo generador de los datos puede expresarse conceptualmente como:

Rendimiento =
3
+ 0.15 × Humedad
+ 2.5 si el suelo es franco
+ error

Por tanto, el análisis busca estudiar:

Observaciones metodológicas importantes

  • Los datos son simulados, no observaciones reales.
  • set.seed(42) garantiza reproducibilidad en R, pero no necesariamente genera exactamente los mismos números que Python, aunque se utilice la misma semilla.
  • El análisis descriptivo no demuestra causalidad.
  • El código no realiza pruebas de hipótesis ni calcula valores p.
  • Tampoco ajusta un modelo estadístico formal que incluya simultáneamente textura, zona, humedad e interacciones.

Para un análisis agrícola más completo, podría ajustarse un modelo como:

modelo <- lm(
  Rendimiento_ton_ha ~ Humedad_ * Textura_Suelo + Zona,
  data = df_lotes_r
)

summary(modelo)

Este modelo permitiría evaluar formalmente:

  • efecto de la humedad;
  • efecto de la textura;
  • efecto de la zona;
  • interacción entre humedad y textura;
  • incertidumbre y significancia estadística de cada efecto.