Análisis de macronutrientes - CoDA

Author

Sergio A. Prieto

Contextualización

Un grupo de ingenieros agrónomos evalúa la composición de macronutrientes en n= 120 parcelas agrícolas dedicadas al cultivo de aguacate Hass. Para cada parcela, el laboratorio analiza la concentración relativa de \(D= 4\) nutrientes clave en la capa arable del suelo:

• \(x_1\): Nitrógeno (\(N\)) (crecimiento vegetativo y masa foliar),

• \(x_2\): Fósforo (\(P\)) (desarrollo radicular y floración),

• \(x_3\): Potasio (\(K\)) (llenado del fruto y resistencia al estrés hídrico),

• \(x_4\): Calcio y Magnesio (\(Ca + Mg\)) (estabilidad de membranas y fotosíntesis).

Base de datos

library(compositions)
Welcome to compositions, a package for compositional data analysis.
Find an intro with "? compositions"

Attaching package: 'compositions'
The following objects are masked from 'package:stats':

    anova, cor, cov, dist, var
The following object is masked from 'package:graphics':

    segments
The following objects are masked from 'package:base':

    %*%, norm, scale, scale.default
# Apertura base de datos
datos = read.csv("suelo.txt",sep = " ")
# Base de datos original
print(head(datos))
  nitrogeno    fosforo   potasio calcio_mg
1 0.2922582 0.34522725 0.2251524 0.5956858
2 0.1808293 0.39974974 0.2101890 0.2661557
3 0.2606640 0.11623533 0.3425477 0.2668081
4 0.2437240 0.17914310 0.2781906 0.3258615
5 0.2046843 0.03229637 0.1995944 0.5883050
6 0.1175230 0.13562875 0.1980997 0.5628230
# Convertir datos en formato acomp
datos_comp = acomp(datos)
# Base de datos composicional
print(head(datos_comp))
  nitrogeno   fosforo      potasio     calcio_mg  
1 "0.2004070" "0.23672883" "0.1543913" "0.4084730"
2 "0.1710902" "0.37822003" "0.1988686" "0.2518211"
3 "0.2642967" "0.11785523" "0.3473216" "0.2705264"
4 "0.2373351" "0.17444711" "0.2708983" "0.3173195"
5 "0.1997154" "0.03151234" "0.1947490" "0.5740232"
6 "0.1158919" "0.13374634" "0.1953503" "0.5550115"
attr(,"class")
[1] "acomp"

Se tiene que el promedio de los datos pos cada nutriente es:

# Media de los datos composicionales
g = mean(datos_comp)
print(g)
  nitrogeno     fosforo     potasio   calcio_mg 
"0.2394719" "0.1088871" "0.2018551" "0.4497859" 
attr(,"class")
[1] "acomp"
# Graficas ternarias
plot(datos_comp, col = "cyan3", cex = 0.8)

plot(g, add = TRUE , col = "red", pch = 19, cex = 0.8)
title(main = "Grafico de los datos con respecto a la media", line = 3)

Se tiene una concentración en promedio mayor de Calcio y magnesio, seguido por nitrogeno, potasio y fosforo. Lo cual podría indicar una buena estabilidad de las membranas y por tanto un buen proceso de fotosíntesis, además, se tendrá un buen crecimiento vegetativo y frutación, pero puede que la floración no sea muy representativa con respecto a las demás características.

Matriz de variaciones

# Matriz de variaciones 
var_matrix = variation(datos_comp) # Normal
print(round(var_matrix,4))
          nitrogeno fosforo potasio calcio_mg
nitrogeno    0.0000  0.4727  0.2512    0.1856
fosforo      0.4727  0.0000  0.4915    0.4686
potasio      0.2512  0.4915  0.0000    0.2385
calcio_mg    0.1856  0.4686  0.2385    0.0000

En general las mayores variaciones se tienen con respecto al fosforo, iniciando por el potasio, seguido por nitrogeno y finalmente calcio y magnesio, \[\ln{\frac{K}{P}},~\ln{\frac{N}{P}},~\ln{\frac{Ca + Mg}{P}}\] lo cual tiene sentido, ya que el fosforo presenta la menor concentración promedio.

Matriz de varianza de la transformación clr

# Transformacion clr
datos_clr = clr(datos_comp)
# Matriz de varianza de clr
cov_matrix_clr = cov(datos_clr)
print(round(cov_matrix_clr,4))
          nitrogeno fosforo potasio calcio_mg
nitrogeno    0.0956 -0.0753 -0.0210    0.0007
fosforo     -0.0753  0.2265 -0.0758   -0.0754
potasio     -0.0210 -0.0758  0.1136   -0.0168
calcio_mg    0.0007 -0.0754 -0.0168    0.0914

Como se tiene la propiedad de las covarianzas negativas forzadas (Suma cero por filas y columnas) no es posible hacer una interpretación directa de la matriz de covarianzas de la transformación \(clr\).

Varianza total

# Totvar clr
totvar_clr = sum(diag(cov_matrix_clr))
cat("La varianza total es:",totvar_clr)
La varianza total es: 0.5270697

La varianza total no tiene una interpretación directa ya que no existe un valor de referencia para identificar cuan representativa esta es.

Matriz de variaciones relativa

Para determinar la matriz de variaciones relativa se necesita normalizar la matriz de datos

# Matriz normalizada
D = ncol(datos_comp)
T_doble_star = var_matrix/(2*D*totvar_clr)
# Variablilidad relativa
# Matriz de variaciones relativa
print(round(T_doble_star, 4))
          nitrogeno fosforo potasio calcio_mg
nitrogeno    0.0000  0.1121  0.0596    0.0440
fosforo      0.1121  0.0000  0.1166    0.1111
potasio      0.0596  0.1166  0.0000    0.0566
calcio_mg    0.0440  0.1111  0.0566    0.0000
# Matriz de variaciones relativa en porcentaje
print(round(T_doble_star, 4)*100)
          nitrogeno fosforo potasio calcio_mg
nitrogeno      0.00   11.21    5.96      4.40
fosforo       11.21    0.00   11.66     11.11
potasio        5.96   11.66    0.00      5.66
calcio_mg      4.40   11.11    5.66      0.00
# Mapa de calor de la variabilidad relativa
T_doble_star_matrix = as.matrix(T_doble_star)
heatmap(T_doble_star_matrix, Rowv = NA, 
  Colv = NA, scale = "none", main = "", margins = c(8, 8), cexRow = 0.7, cexCol = 0.7, cex.main = 0.5)
title(
  main = expression("Mapa de calor de la matriz de variabilidad relativa"), 
  line = 3.5         # Distancia vertical respecto al gráfico
)

Se evidencia que la la varianza está principalmente explicada por el fósforo, ya que este nutriente se presenta en una concentración relativa menor a los demás elementos en las parcelas estudiadas.

Estandarización de los datos

# Estandarizacion de los datos
datos_cent = datos_comp - g
z = (1/sqrt(totvar_clr))* datos_cent
# Centro
print('El centro de Z')
[1] "El centro de Z"
print(mean(z))
nitrogeno   fosforo   potasio calcio_mg 
   "0.25"    "0.25"    "0.25"    "0.25" 
attr(,"class")
[1] "acomp"
# Totvar z
cat("Varianza total de Z: ",sum(diag(cov(z))))
Varianza total de Z:  1

Se tiene que se cumplen las propiedades de la matriz de datos estandarizada, tal que, \[\text{Centro}(Z)=\left(\frac{1}{4},\frac{1}{4},\frac{1}{4},\frac{1}{4} \right) = \left(0.25,0.25,0.25,0.25 \right) \\ \text{totvar}(Z)= \frac{1}{2(4)}\sum_{j=1}^4 \sum_{k=1}^4 \text{var}\left( \ln{\frac{z_j}{z_k}} \right) = 1\]

Contextualización

El equipo de nutrición vegetal establece la siguiente Partición Binaria Secuencial (SBP) fisiológica:

• \(b_1\) (Nutrientes Principales vs. Secundarios/Estructurales): Compara el bloque de mayor demandainstantánea \(\{N,P,K\}\) frente al complejo estructural \(\{Ca+ Mg\}\).

• \(b_2\) (Crecimiento Vegetativo vs. Reproducción/Fruto): Compara la fuente del follaje \(\{N\}\) frente al bloque de floración y llenado \(\{P,K\}\).

• \(b_3\) (Balance de Carga Radicular y Fruto): Compara fósforo \(\{P\}\) frente a potasio \(\{K\}\).

Matriz de signos y de contrastes

La matriz de signos está dada por \[\Theta = \begin{pmatrix} 1 & 1 & 0 \\ 1 & -1 & 1 \\ 1 & -1 & -1\\ -1 & 0 & 0 \end{pmatrix}\]

# Matriz de signos
sign_matrix = matrix(c(
  1, 1, 1, -1,  # b1
  1, -1, -1, 0,  #b2
  0, 1, -1, 0 #b3
), nrow = 4, byrow = F)
print(sign_matrix)
     [,1] [,2] [,3]
[1,]    1    1    0
[2,]    1   -1    1
[3,]    1   -1   -1
[4,]   -1    0    0

La matriz de contrastes está dada por \[V = \begin{pmatrix} \frac{1}{3}\sqrt{\frac{3}{4}} & \sqrt{\frac{2}{3}} & 0 \\ \frac{1}{3}\sqrt{\frac{3}{4}} & -\frac{1}{2}\sqrt{\frac{2}{3}} & \sqrt{\frac{1}{2}} \\ \frac{1}{3}\sqrt{\frac{3}{4}} & -\frac{1}{2}\sqrt{\frac{2}{3}} & -\sqrt{\frac{1}{2}} \\ -\sqrt{\frac{3}{4}} & 0 & 0 \end{pmatrix}\]

# Matriz de contrastes
V = gsi.buildilrBase(sign_matrix)
print(V)
           [,1]       [,2]       [,3]
[1,]  0.2886751  0.8164966  0.0000000
[2,]  0.2886751 -0.4082483  0.7071068
[3,]  0.2886751 -0.4082483 -0.7071068
[4,] -0.8660254  0.0000000  0.0000000

Varianza de los balances

# Coordenadas ilr o balances
datos_ilr = ilr(datos_comp, V = V)

# Varianza de los balances
var_b1 = var(datos_ilr[,1])
var_b2 = var(datos_ilr[,2])
var_b3 = var(datos_ilr[,3])

cat("var(b1) = ", var_b1, ", var(b2) = ", var_b2, ", var(b3) = ", var_b3)
var(b1) =  0.1219103 , var(b2) =  0.1594029 , var(b3) =  0.2457565
cat("Totvar(X) = ",totvar_clr)
Totvar(X) =  0.5270697
cat("var(b1) + var(b2) + var(b3) = ",var_b1,"+",var_b2,"+",var_b3, " = ", var_b1+var_b2+var_b3)
var(b1) + var(b2) + var(b3) =  0.1219103 + 0.1594029 + 0.2457565  =  0.5270697

Con lo que se prueba que \[\text{var}(b_1) + \text{var}(b_2) + \text{var}(b_3) = 0.1219103 + 0.1594029 + 0.2457565 = 0.5270697 = \text{totvar}(X) \]

Biplot

Biplot de covarianza

# PCA
pca_X = prcomp(datos_clr, center = TRUE, scale. = FALSE)

# Biplot de covarianza
par(mar = c(4, 3, 4, 1)) 
biplot(pca_X, scale = 0, col = c("black", "red"), lwd = 1, cex = c(0.7, 0.7), arrow.len = 0.05, xlabs = rep("•", nrow(datos))  , xlim = c(-1.6,1.6), ylim = c(-1,1))
title("Bipot de covarianza", line = 3)

Se puede observar que hay varias parcelas cuyas covarianzas son elevadas principalmente entre los nutrientes Nitrógeno - Calcio_Magnesio - Potasio y Nitrógeno - Fósforo. Además, el rayo más largo es el correspondiente al nutriente potasio seguido del fósforo, lo cual implica que este par de nutrientes introducen la mayor variabilidad relativa, mientras que los nutrientes Nitrógeno y Calcio - Magnesio mantienen la variabilidad similar entre sí dada la longitud de los enlaces, de igual manera los rayos son más cortos por lo que la variabilidad es mas cercana al centro o la media de los datos. Por otro lado, se tiene que los nutrientes Nitrógeno, Calcio - Magnesio y Potasio parecen ser colineales por lo que forman un subsistema líneal.

Biplot de forma

# Biplot de forma
par(mar = c(4, 3, 4, 1)) 
biplot(pca_X, scale = 1, col = c("black", "red"), lwd = 1, cex = c(0.7, 0.7), arrow.len = 0.05, xlabs = rep("•", nrow(datos))  , xlim = c(-0.3,0.3), ylim = c(-0.25,0.25))
title("Bipot de forma", line = 3)

Se observa que los vínculos entre el Fósforo y los demás nutrientes presentan enlaces largos por lo que las proporciones son diferentes entre sí, mientras que el enlace entre los nutrientes Nitrógeno y Calcio - Magnesio es el más corto por lo que su varianza relativa es casi cero. Además, la flecha del nutriente Fósforo es la más larga seguido por el Potasio por lo que estas son las componentes que más varían con respecto a la media geométrica. Por otro lado, también se tiene que los rayos de los nutrientes Nitrógeno, Calcio - Magnesio y Potasio parecen ser colineales de modo que se pueden comportar como un subsistema líneal.

Dendograma

# Dendrograma CoDa
par(cex.axis = 0.8)
CoDaDendrogram(datos_comp, V = V)
title(main = "Dendrograma de balances" )

\(b_1 = \left\{[N,P,K] vs. [Ca+ Mg]\right\}\):

Se tiene que la varianza es baja, además, que los datos parecen simétricos con respecto a la mediana sin embargo se tiene que los datos tienden hacia \([N,P,K]\) por lo que el cociente-log es positivo.

\(b_2 = \left\{[N] vs. [P,K] \right\}\):

Se observa que la varianza también es baja, también, se tiene que mediana se ubica negativa de forma que los datos tienen una mayor densidad hacia \([P,K]\) es decir que el cociente-log es negativo aunque los bigotes son simétricos.

\(b_3 = \left\{[P] vs. [K] \right\}\):

La varianza es mayor respecto a los balances \(b_1\) y \(b_2\), por otro lado, el diagrama de caja y bigotes parece ser simétrico con la mediana centrada con respecto a los datos por lo que la proporción es altamente estable entre ambos nutrientes.