# Manejo de datos
library(dplyr)
# Manejo de datos espaciales
library(sf)
# Graficos
library(ggplot2)
# Mapas y graficos de datos espaciales
library(tmap)
# Ajuste de modelos Mixtos
library(nlme)
# Comparacion de medias
library(emmeans)
Ensayo Agricultura de Precisión - Regresión
- Se evaluaron cuatro dosis de nitrógeno (N) en cuatro zonas de manejo.
- Es de interés conocer la dosis óptima de nitrogeno para cada zona homogénea.
Estadistica descriptiva
Se realiza un muestreo de la base de datos dado la demora computacional en el ajuste del modelo con correlación espacial.
set.seed(2025)
<- read_sf('Datos/Dia 1/Ensayo/EnsayoCurso.shp')
datos_ensayo_n
<-
datos_ensayo_n |>
datos_ensayo_n mutate(Z = as.character(Z),
N2 = N * N) |>
group_by(N, Z) |>
slice_sample(prop = 0.15)
<-
datos_ensayo_n cbind(datos_ensayo_n,
st_coordinates(datos_ensayo_n))
head(datos_ensayo_n)
Lote | Rto | N | Z | N2 | X | Y | geometry |
---|---|---|---|---|---|---|---|
LP08 | 6478.404 | 0 | 1 | 0 | 416415.4 | 6304603 | POINT (416415.4 6304603) |
LP08 | 6500.213 | 0 | 1 | 0 | 416725.4 | 6304614 | POINT (416725.4 6304614) |
LP08 | 6507.766 | 0 | 1 | 0 | 416902.8 | 6304605 | POINT (416902.8 6304605) |
LP08 | 6416.383 | 0 | 1 | 0 | 416954.2 | 6304624 | POINT (416954.2 6304624) |
LP08 | 6428.191 | 0 | 1 | 0 | 416415.8 | 6304613 | POINT (416415.8 6304613) |
LP08 | 6122.872 | 0 | 1 | 0 | 416417.6 | 6304603 | POINT (416417.6 6304603) |
tm_shape(datos_ensayo_n) +
tm_dots(fill = 'Rto')
tm_shape(datos_ensayo_n) +
tm_dots(fill = 'Z',
fill.scale = tm_scale_categorical())
tm_shape(datos_ensayo_n) +
tm_dots(fill = 'N',
fill.scale = tm_scale_categorical())
ggplot(datos_ensayo_n, aes(N, Rto, color = Z, group = Z)) +
stat_summary()
No summary function supplied, defaulting to `mean_se()`
Ajuste de modelo
El modelo ajustado considera el rendimiento (\(\text{Rto}\)) en función de la zona (\(Z\)), la dosis de nitrógeno (\(N\)) y sus interacciones hasta el tercer orden.
\[ \begin{align*} \text{Rto}_i &= \beta_0 + \beta_1 \text{Z}_i + \beta_2 \text{N}_i + \beta_3 \text{N}_i^2 + \beta_4 (\text{Z}_i \cdot \text{N}_i) + \beta_5 (\text{Z}_i \cdot \text{N}_i^2) + \beta_6 (\text{Z}_i \cdot \text{N}_i \cdot \text{N}_i^2) + \varepsilon_i \end{align*} \]
Se ajustarán modelos de errores independientes (\(\varepsilon \sim \mathcal{N}(0,I \sigma^2)\)) y modelos que contemplen la correlación espacial en función de las coordenadas \(X\) e \(Y\), sin efecto nugget: \[ \varepsilon \sim \mathcal{N}(0, \sigma^2 \Sigma) \]
Ajuste de modelo
Sin contemplar correlación espacial
<- gls(Rto ~ N + N2 + Z + N*Z + N2*Z + N*N2*Z,
mdl_errores_indep data = datos_ensayo_n)
Contemplando correlación espacial
<- gls(Rto ~ N + N2 + Z + N*Z + N2*Z + N*N2*Z,
mdl_errores_corr_exp correlation = corExp(form=~ X + Y,
nugget=FALSE,
metric='euclidean'),
data = datos_ensayo_n)
<- gls(Rto ~ N + N2 + Z + N*Z + N2*Z + N*N2*Z,
mdl_errores_corr_gau correlation = corGaus(form=~ X + Y,
nugget=FALSE,
metric='euclidean'),
data = datos_ensayo_n)
<- gls(Rto ~ N + N2 + Z + N*Z + N2*Z + N*N2*Z,
mdl_errores_corr_lin correlation = corLin(form=~ X + Y,
nugget=FALSE,
metric='euclidean'),
data = datos_ensayo_n)
<- gls(Rto ~ N + N2 + Z + N*Z + N2*Z + N*N2*Z,
mdl_errores_corr_spher correlation = corSpher(form=~ X + Y,
nugget=FALSE,
metric='euclidean'),
data = datos_ensayo_n)
<- gls(Rto ~ N + N2 + Z + N*Z + N2*Z + N*N2*Z,
mdl_errores_corr_rationalquadcorrelation = corRatio(form=~ X + Y,
nugget=FALSE,
metric='euclidean'),
data = datos_ensayo_n)
Comparacion de modelos
La comparación de los modelos se realiza en términos de AIC y BIC. Menor valor de índice indica mejor ajuste.
data.frame(
Modelo = c('Errores Independientes',
'Correlacion Espacial (Exp)',
'Correlacion Espacial (Gaussian)',
'Correlacion Espacial (Linear)',
'Correlacion Espacial (Spheric)',
'Correlacion Espacial (Rational Quadratic)'),
AIC = c(AIC(mdl_errores_indep),
AIC(mdl_errores_corr_exp),
AIC(mdl_errores_corr_gau),
AIC(mdl_errores_corr_lin),
AIC(mdl_errores_corr_spher),
AIC(mdl_errores_corr_rationalquad)),
BIC = c(BIC(mdl_errores_indep),
BIC(mdl_errores_corr_exp),
BIC(mdl_errores_corr_gau),
BIC(mdl_errores_corr_lin),
BIC(mdl_errores_corr_spher),
BIC(mdl_errores_corr_rationalquad))
|>
) arrange(AIC, BIC)
Modelo | AIC | BIC |
---|---|---|
Correlacion Espacial (Exp) | 14828.11 | 14914.71 |
Correlacion Espacial (Linear) | 14899.51 | 14986.11 |
Correlacion Espacial (Spheric) | 14899.51 | 14986.11 |
Correlacion Espacial (Rational Quadratic) | 14915.44 | 15002.05 |
Correlacion Espacial (Gaussian) | 15012.82 | 15099.42 |
Errores Independientes | 15088.72 | 15170.51 |
Modelo final
Se realiza una eliminación de valores extremos. Valores extremos son aquellos valores poco probables de ocurrir en el contexto del modelo ajustado.
<-
datos_ensayo_n_noout abs(residuals(mdl_errores_corr_exp, type = 'normalized')) < 3,]
datos_ensayo_n[
<- gls(Rto ~ N + N2 + Z + N*Z + N2*Z,
mdl_errores_corr_exp correlation = corExp(form=~ X + Y,
nugget=FALSE,
metric='euclidean'),
data = datos_ensayo_n_noout)
$resid_corr_exp <-
datos_ensayo_n_nooutresiduals(mdl_errores_corr_exp, type = 'normalized')
$pred_corr_exp <-
datos_ensayo_n_nooutpredict(mdl_errores_corr_exp)
::ggplot(datos_ensayo_n_noout, ggplot2::aes(sample = resid_corr_exp)) +
ggplot2::geom_qq(
ggplot2colour = "black",
fill = "aquamarine3",
size = 2,
shape = 21
+
) ::geom_qq_line() +
ggplot2::theme_bw() +
ggplot2::labs(y = "Standardised Residual", x = "Theoretical")
ggplot2::ggplot(
ggplot2data = datos_ensayo_n_noout,
mapping = ggplot2::aes(x = pred_corr_exp, y = resid_corr_exp)
+
) ::geom_point(
ggplot2colour = "black",
fill = "aquamarine3",
size = 2,
shape = 21
+
) ::theme_bw() +
ggplot2::labs(y = "Standardised Residual", x = "Fitted Value")
ggplot2::ggplot(
ggplot2data = datos_ensayo_n_noout,
mapping = ggplot2::aes(x = Z, y = resid_corr_exp)
+
) ::geom_boxplot(
ggplot2colour = "black",
fill = "aquamarine3",
size = 2,
shape = 21
+
) ::theme_bw() +
ggplot2::labs(y = "Standardised Residual", x = "Zona")
ggplot2::ggplot(
ggplot2data = datos_ensayo_n_noout,
mapping = ggplot2::aes(x = N, y = resid_corr_exp)
+
) ::geom_point(
ggplot2colour = "black",
fill = "aquamarine3",
size = 2,
shape = 21
+
) ::theme_bw() +
ggplot2::labs(y = "Standardised Residual", x = "Nitrogeno") ggplot2
joint_tests(mdl_errores_corr_exp)
model term | df1 | df2 | F.ratio | p.value | |
---|---|---|---|---|---|
1 | N | 1 | 748.19 | 71.015 | 0.0000000 |
3 | N2 | 1 | 772.05 | 22.751 | 0.0000022 |
5 | Z | 3 | 573.64 | 8.920 | 0.0000088 |
2 | N:Z | 3 | 874.97 | 11.393 | 0.0000002 |
4 | N2:Z | 3 | 877.05 | 4.184 | 0.0059351 |
<- emmeans(mdl_errores_corr_exp, c("Z", "N"), type = "response")
modelb ::cld(modelb, Letters = LETTERS, alpha = 0.05) |>
multcompas.data.frame(row.names = NULL) |>
::rename(mean = emmean) dplyr
Z | N | mean | SE | df | lower.CL | upper.CL | .group | |
---|---|---|---|---|---|---|---|---|
4 | 4 | 217.4645 | 7191.933 | 353.3154 | 9.249300 | 6395.950 | 7987.917 | A |
3 | 3 | 217.4645 | 7733.930 | 334.2457 | 7.617351 | 6956.366 | 8511.494 | B |
1 | 1 | 217.4645 | 8107.623 | 330.1085 | 7.083304 | 7328.898 | 8886.349 | BC |
2 | 2 | 217.4645 | 8156.014 | 324.5728 | 6.811757 | 7384.201 | 8927.828 | C |
coefficients(mdl_errores_corr_exp)
(Intercept) N N2 Z2 Z3
5.789522e+03 1.761205e+01 -2.071094e-02 4.061305e+02 7.127285e+02
Z4 N:Z2 N:Z3 N:Z4 N2:Z2
9.791665e+02 -2.265393e+00 -7.998081e+00 -1.487809e+01 1.847995e-03
N2:Z3 N2:Z4
8.943546e-03 1.836445e-02
Grafico de modelo ajustado
Grilla de predicción
<- datos_ensayo_n_noout |>
range_n_by_zone st_drop_geometry() |>
group_by(Z) |>
summarise(min_N = min(N), max_N = max(N))
<- range_n_by_zone |>
grid_pred rowwise() |>
do({
data.frame(
Z = .$Z,
N = seq(.$min_N, .$max_N, length.out = 100)
)|>
}) ungroup() |>
mutate(
N2 = N^2
)
Prediccion de rendimiento
$Rto_pred <- predict(mdl_errores_corr_exp, newdata = grid_pred) grid_pred
Optima dosis de N para cada zona
<- grid_pred %>%
opt_n_by_zone group_by(Z) %>%
slice_max(Rto_pred, n = 1, with_ties = FALSE) |>
select(Z, N, Rto_pred)
opt_n_by_zone
Z | N | Rto_pred |
---|---|---|
1 | 426.6667 | 9533.686 |
2 | 408.8889 | 9317.032 |
3 | 408.8889 | 8465.904 |
4 | 440.0000 | 7517.349 |
Grafico de rendimientos predichos
ggplot(grid_pred, aes(x = N, y = Rto_pred, color = Z)) +
geom_line() +
geom_point(data = opt_n_by_zone, aes(x = N, y = Rto_pred), size = 3) +
labs(x = "Dosis de N", y = "Rendimiento predicho (Kg/ha)") +
theme_minimal()