Uso de soilquality para calcular el índice de calidad de suelo (SQI)

Tabla de contenidos

Introducción

Para manejar la complejidad y los múltiples aspectos de las propiedades del suelo, los investigadores y profesionales utilizan el índice de calidad de suelo (SQI) como herramienta clave. El objetivo principal del SQI es combinar diversos indicadores físicos, químicos y biológicos del suelo en una única puntuación global sin unidades. Esta agregación simplifica los datos complejos y multivariantes, lo que permite generar una métrica clara y fácil de entender que facilita la toma de decisiones de gestión informadas.

Hace un tiempo se trabajó una aplicación usando R junto con Shiny con el objetivo de crear un entorno amigable que permita realizar el cálculo del SQI e inclusive realizar interpolación para generar un mapa de superficie de éstos valores. Ahora, luego de realizar una profunda revisión de estudios recientes, he visto que usan el análisis de componentes principales (PCA) y el proceso jerárquico analítico (AHP) para establecer un conjunto de datos mínimo (MDS) y evaluar las propiedades físicas y químicas clave que afectan a la calidad del suelo, junto con el factor de ponderación asociado a cada indicador [1]. Todo esto me motivó al desarrollo del paquete de R soilquality.

Las características principales de soilquality son:

  • Selección automática del Conjunto de Datos Mínimo (MDS): Reducción de dimensionalidad basada en Análisis de Componentes Principales (PCA).
  • Sistema de ponderación experta: Metodología del Proceso Analítico Jerárquico (AHP) con validación del índice de consistencia.
  • Funciones de puntuación flexibles: Múltiples métodos de normalización para diferentes propiedades del suelo
  • Visualización integral: Múltiples tipos de gráficos para interpretación de resultados

Flujo de trabajo metodológico

Primero debemos de instalar el paquete soilquality desde el repositorio de GitHub empleando pak de preferencia:

Paso 1: Preparación de datos

Es necesario estandarizar los datos numéricos:

Paso 2: Selección del Conjunto de Datos Mínimo (MDS) usando PCA

El conjunto de datos mínimo (MDS) es un subconjunto de indicadores del suelo que mejor representa la calidad general del suelo. El PCA nos ayuda a identificar las variables más importantes que explican la mayor variabilidad en los datos.

Paso 3: Asignación de Pesos usando AHP

El proceso analítico jerárquico (AHP), es un método de toma de decisiones multicriterio que permite asignar pesos a los indicadores basándose en comparaciones pareadas de su importancia relativa. Los expertos comparan cada par de indicadores usando la escala de Saaty (1-9)

ValorSignificado
1Igual importancia
3Importancia moderada
5Importancia fuerte
7Importancia muy fuerte
9Importancia extrema
2,4, 6, 8Valores intermedios

Crear matriz AHP de forma interactiva

De manera automática va realizar una análisis de consistencia (CR), donde un CR < 0.10 indica que las comparaciones son consistentes y los pesos son confiables.

Paso 4: Funciones de Puntuación

El paquete ofrece diferentes métodos para transformar valores de propiedades del suelo a puntuaciones (0-1):

A. Función Lineal: Más es Mejor (higher_better)

La función score_higher_better() se utiliza cuando la calidad del suelo presenta una mejora continua a medida que aumenta el valor del indicador evaluado. A diferencia de otras funciones, no se establece un valor óptimo ni un umbral crítico más allá del cual el indicador genere efectos adversos. Esta función asume una relación proporcional y monótona creciente entre el indicador y la calidad edáfica, siendo apropiada para propiedades como el contenido de materia orgánica, la capacidad de intercambio catiónico o la disponibilidad de nutrientes esenciales.

En otras palabras, cada aumento unitario en las propiedades del suelo contribuye por igual a mejorar la calidad del suelo.

B. Función Lineal: Menos es Mejor (lower_better)

La función score_lower_better() se utiliza cuando el indicador evaluado representa una condición de estrés, limitación o degradación del suelo. Bajo este esquema, valores mayores del indicador se asocian con una reducción de la calidad edáfica. Este comportamiento es típico de propiedades que reflejan limitaciones físicas (como la densidad aparente o la resistencia a la penetración) o la acumulación de elementos tóxicos (como sales solubles o metales pesados).

C. Función No Lineal: Rango Óptimo (optimum_range)

La función score_optimum(), se emplea cuando la calidad del suelo alcanza su valor máximo en un punto intermedio, disminuyendo progresivamente cuando el indicador se aleja de este óptimo, ya sea por valores superiores o inferiores. Este patrón refleja la naturaleza de múltiples procesos biológicos y químicos del suelo que requieren condiciones específicas para su funcionamiento adecuado.

El pH constituye el ejemplo más común: valores extremadamente ácidos (pH < 5.0) limitan la disponibilidad de nutrientes esenciales y aumentan la toxicidad de elementos como aluminio y manganeso, mientras que valores alcalinos (pH > 8.0) reducen la disponibilidad de micronutrientes (Fe, Mn, Zn, Cu) y pueden inducir deficiencias nutricionales. El rango óptimo (generalmente pH 6.0-7.0 para la mayoría de cultivos) maximiza la disponibilidad de nutrientes, la actividad microbiana y la mineralización de la materia orgánica.

La penalización («penalty») es una función de pérdida aplicada a la desviación del valor óptimo, convertida en una puntuación. Con la penalización lineal, la puntuación disminuye a un ritmo constante a medida que se aleja del valor óptimo. Con la penalización cuadrática, la puntuación disminuye lentamente cerca del valor óptimo (ya que al elevar al cuadrado un número pequeño se reduce), pero con mayor intensidad a medida que se acerca al límite de tolerancia.

El método cuadrático otorga puntuaciones más altas que el lineal para la misma desviación; es decir, es más tolerante, excepto en los puntos finales (ambos dan 1 en el óptimo y 0 en la tolerancia).

Significado práctico en los indicadores de suelo:

Lineal: se busca que las desviaciones afecten de forma inmediata y proporcional.
Cuadrático: se aceptan las desviaciones moderadas como «en general aceptables», pero se busca castigar las desviaciones grandes a medida que se acerca al límite.

D. Función No Lineal: Umbrales Personalizados (threshold_scoring)

La función score_threshold() es empleado cuando la relación entre el indicador y la calidad del suelo no es continua, sino que presenta cambios discretos en niveles críticos definidos. Este método establece múltiples umbrales basados en criterios agronómicos o ecológicos, asignando puntuaciones específicas a cada intervalo. Las implicaciones principales son: (i) permite incorporar conocimiento experto sobre niveles críticos de suficiencia o toxicidad; (ii) reconoce que pequeños incrementos del indicador por debajo de un umbral pueden no mejorar la calidad del suelo; (iii) captura transiciones abruptas en la funcionalidad edáfica, como el paso de deficiencia severa a disponibilidad adecuada de nutrientes. Esta función es particularmente apropiada para nutrientes con niveles críticos establecidos (P, K, micronutrientes) o contaminantes con umbrales de toxicidad definidos.

Podemos aplicar puntuaciones a múltiples indicadores:

En resumen, se pueden utilizar ecuaciones lineales y no lineales para evaluar el SQI con base a diversas propiedades del suelo, pero son las propiedades biológicas las más determinantes para evaluar el impacto de la cambio de uso del suelo sobre el valor de su calidad [2].

Paso 5: Cálculo del Índice de Calidad del Suelo (SQI)

Se puede realizar el flujo de trabajo completo automatizado:

Paso 6: Visualización de Resultados

Generación de gráficos de distribución del SQI

Podemos generar un reporte completo multipanel

Interpretación de Resultados

Se podría generar una tabla para interpretar los resultados.

Rango SQICategoríaInterpretación
0.80 – 1.00ExcelenteSuelo de muy alta calidad, óptimo para cultivos
0.60 – 0.79BuenoSuelo de buena calidad, adecuado para la mayoría de cultivos
0.40 – 0.59ModeradoCalidad moderada, requiere manejo para mejorar
0.20 – 0.39BajoBaja calidad, necesita intervención significativa
0.00 – 0.19Muy BajoCalidad muy baja, limitaciones severas

Reflexiones Finales

El paquete soilquality proporciona un grupo de funciones que nos permite evaluar de manera robusta y flexible la calidad del suelo a través de métodos cuantitativos. La integración de PCA para la selección de MDS y AHP para la ponderación de indicadores garantiza un enfoque científicamente fundamentado que puede adaptarse a diferentes contextos edáficos y objetivos de manejo.

Una importante fase de este proceso de cálculo radica en la utilización de funciones de puntuaciones lineales y no lineales. Esto nos permite capturar la compleja relación entre propiedades del suelo y su calidad funcional, lo que nos demuestra la flexibilidad del paquete, pero también su robustez para establecer relaciones y puntuaciones específicas para cada propiedad del suelo. Finalmente el poder contar con herramientas de visualización, nos facilita la comunicación de los resultados finales.

Existe algunas funciones del paquete que no fueron exploradas pero que podrían implementarse. Espero que una vez practicado los scripts presentados, podamos profundizar en otras opciones un poco más complejas.

Referencias

  1. Ibrahim, H. M., Alasmary, Z., Majrashi, M. A., Harbi, M. A., Abldubise, A., Alghamdi, A. G., Ibrahim, H. M., Alasmary, Z., Majrashi, M. A., Harbi, M. A., Abldubise, A., & Alghamdi, A. G. (2025). Application of Principal Component and Multi-Criteria Analysis to Evaluate Key Physical and Chemical Soil Indicators for Sustainable Land Use Management in Arid Rangeland Ecosystems. Land, 14(11). https://doi.org/10.3390/land14112167
  2. Pouladi, N., Jafarzadeh, A.A., Shahbazi, F. et al. Assessing the soil quality index as affected by two land use scenarios in Miandoab region. SN Appl. Sci. 2, 1875 (2020). https://doi.org/10.1007/s42452-020-03651-9

Gitea una opción para tener un servicio Git propio

Tabla de contenidos

Introducción

Cuando desarrollamos nuestro proyectos siempre buscamos la manera de trabajarlo en un ambiente práctico y seguro, en la actualidad existen diversos servicios para contar con repositorios remotos bajo los sistemas de control de versiones de Git (GitLab, GitHub, BitBucket, entre otros), pero de alguna manera estamos limitados a ciertas características propios de cada servicio. Desde hace unos años apareció Gitea como una opción libre para contar con el servicio pero alojado de manera local en nuestra infraestructura, lo que me parece una interesante alternativa para quienes estamos acostumbrados a gestionar repositorios. A continuación voy a mostrar mi experiencia instalando Gitea a través de Docker, en la documentación de Gitea puedes revisar otras opciones.

Instalación usando Docker

Primeros Pasos

Lo primeo que hice fue generar una carpeta en donde voy a trabajar Gitea, en mi caso lo abrí con Visual Studio Code y generé una archivo YAML al que le denominé docker-compose.yml , el contenido de este archivo lo extraje de la documentación de Gitea, el cual correspondía a la instalación usando Docker y en donde se especifica el uso de Gitea en combinación con una base de datos MySQL.

version: "3"

networks:
  gitea:
    external: false

services:
  server:
    image: docker.io/gitea/gitea:1.23.1
    container_name: gitea
    environment:
      - USER_UID=1000
      - USER_GID=1000
+     - GITEA__database__DB_TYPE=mysql
+     - GITEA__database__HOST=db:3306
+     - GITEA__database__NAME=gitea
+     - GITEA__database__USER=gitea
+     - GITEA__database__PASSWD=gitea
    restart: always
    networks:
      - gitea
    volumes:
      - ./gitea:/data
      - /etc/timezone:/etc/timezone:ro
      - /etc/localtime:/etc/localtime:ro
    ports:
      - "3000:3000"
      - "222:22"
+    depends_on:
+      - db
+
+  db:
+    image: docker.io/library/mysql:8
+    restart: always
+    environment:
+      - MYSQL_ROOT_PASSWORD=gitea
+      - MYSQL_USER=gitea
+      - MYSQL_PASSWORD=gitea
+      - MYSQL_DATABASE=gitea
+    networks:
+      - gitea
+    volumes:
+      - ./mysql:/var/lib/mysql

Luego de contar con el archivo, dentro de VsCode abrí una terminal, en mi caso lo hice con GitBash para mayor facilidad, desde ahí ejecuté el siguiente comando:

docker-compose up -d

Ajustes requeridos

Un detalle que no debemos dejar de lado son los requerimientos para una instalación sin errores, uno de ellos es el contar con Docker Desktop corriendo en nuestro equipo. Por otro lado, si fueron curiosos y vieron la figura de arriba, en la línea 26 se define los puertos a emplearse, en mi caso el puerto por defecto «3000» lo tenía ocupado, por lo tanto, lo modifiqué a «4000», pero no basta hacer eso, aunque me tarde un poco en descubrirlo, es necesario también editarlo del archivo app.ini localizado dentro de la carpeta config.

Para comprobar que todo funciona bien, lo podemos revisar en nuestro Docker Desktop.

También, para quienes tienen el complemento de Docker en VsCode lo podemos apreciar al activarlo de la barra lateral.

Configuración de nuestro servicio

Ahora viene lo interesante, debemos ir a nuestro navegador web para abrir nuestro servicio local, en mi caso iré a: http://localhost:4000/. Cuando hagamos eso nos aparecerá una página para terminar de configurar el servicio con detalles que podemos editar, como por ejemplo el título de la página y lo más importante los datos como administradores. Nos referimos con introducir nuestro correo y una constraseña.

Pasos finales

Luego de introducir los datos requeridos en la configuración inicial podemos hacer click en el botón que dice «Instalar Gitea».

Dentro de nuestro Servicio Git

Una vez que pudimos levantar el servicio podemos iniciar creando un nuevo repositorio, aunque en mi caso lo que empecé hacer fue migrar repositorios que tenía en GitHub por ejemplo, para ello solo seleccionamos esa opción.

Luego seleccionamos desde el sitio, en este caso seleccionamos GitHub y luego podemos ir a nuestro repositorio que vamos a migrar para copiar la URL que usaríamos para clonarlo y lo insertamos en donde indica «Migrar / Clonar desde URL«.

Opciones de Migración

Un detalle que no quiero dejar de pasar en la posibilidad de que los repositorios que migremos pueden ser una réplica, esto quiere decir que estarían sincronizados con el sitio de origen en este caso de un repositorio de GitHub. Cuando listemos nuestros repositorios tendrán un ícono distinto a los otros.

Para mantenerlo actualizado con los últimos cambios que hagamos, no debemos olvidarnos de realizar esta sincronización.

Nuevos Repositorios

Bueno no dejemos de lado también la posibilidad de generar desde cero nuestros repositorios, muy similar a lo que ya conocemos.

Luego que ya sea por migración o creando nuevos repositorios ya podemos visualizarlos si nos vamos a la pestaña de «Explorar» o también dentro de nuestro «Perfil».

Trabajando con los repositorios

Ahora que tenemos nuestros repositorios podemos realizar los cambios o actualizaciones que sean necesarios, por lo tanto, debemos realizar el proceso de clonado, en este caso, nos dá varios opciones, pero creo que abrirlo dentro de VsCode considero que es lo más práctico, solo nos pedirá que seleccionamos una carpeta en donde se va a descargar.

Reflexión Final

Luego de esta experiencia de poder instalar un servicio autoalojado de Git para gestionar el desarrollo de mis proyectos, siento que tengo un mayor control de mi información, aunque es verdad que la ventaja de tener los servicios de GitHub en términos de colaboración y ser más visibles son muy valiosas, no pienso dejarlos, pero si algunos proyectos lo quisiera manejar de manera local con toda la posibilidad de aprovechar el sistema de control de versiones. Todavía no genero un repositorio desde cero, pero seguro será de un proyecto muy personal y cuando esté muy bien pulido lo podré compartir en los repositorios remotos.

Bueno, esto sería todo por ahora, en esta oportunidad no he generado un video porque todo fue muy rápido y considero que no es muy complicado si seguimos los pasos que se ha descrito, espero que sea de utilidad para quienes se animen. Hasta la próxima.

Exploración de datos con DataVoyager

Tabla de contenidos

Introducción

En busca de herramientas que nos permiten visualizar nuestros datos y a modo de complementar lo que vimos con VegaLite en una entrada anterior, en esta oportunidad probaremos el uso de un paquete de Julia denominado DataVoyager.jl. Nuestro objetivo será mostrar de manera práctica las ventajas de trabajar con una herramienta interactiva de visualización que nos puede ayudar como parte del proceso de exploración inicial de nuestros datos.

Detalles sobre DataVoyager.jl

En principio, debemos entender que este paquete de Julia viene integrado dentro del metapaquete Queryverse, logrando proporcionar herramientas interactivas de exploración de datos. Se basa en el proyecto Voyager y está estrechamente integrado con VegaLite.jl. Como vemos, el paquete usa como fuente Vega, que trabaja a través de una gramática de visualización, un lenguaje declarativo para crear, guardar y compartir diseños de visualización interactivos, el mismo que a través de su aplicativo Voyager presenta una interfaz de visualización para la exploración de datos. Proporciona una interfaz para especificar la especificación Vega-Lite, con recomendaciones de gráficos impulsadas por el motor de recomendación de visualización Compass (como lenguaje de consulta). Como dato adicional, Voyager además de ser utilizado por Julia a través de DataVoyager, para quienes tienen la costumbre de usar JupyterLab, existe una extensión para que lo puedan probar.

Uso de DataVoyager

Para nuestra demostración vamos a emplear unos datos en formato CSV y de libre acceso: Crop Yield and Production. Como primera acción debemos instalar los paquetes requeridos. Podemos desde una IDE como Visual Studio Code, activar el REPL con las teclas Alt j + Alt o, y luego de usar ], adicionamos los paquetes VegaDatasets, DataVoyager, CSVFiles, DataFrames y VegaLite.

(@v1.7) pkg>add <package>

Vamos a generar un archivo que en mi caso lo denominé eda.jl, para iniciar nuestro código activando los paquetes instalados.

using VegaDatasets  
using DataVoyager   
using CSVFiles
using DataFrames
using VegaLite  

Ahora como primer ejemplo emplearemos una de los datos disponibles que tenemos al usar VegaDatasets, nos referimos a «iris«.

dat_iris = dataset("iris") |> Voyager()
Vista de DataVoyager con datos de Iris

Opciones dentro de DataVoyager

Como se aprecia en la imagen previa, en digamos el campo de datos, ha reconocido las columnas de los datos, colocando el símbolo «#» al inicio para aquellos que presentan datos de tipo numérico o cuantitativo y «A«, para aquellos de tipo nominal. A partir de ahora queda a nuestro criterio ir agrupando los datos en los ejes X e Y respectivos (solo se arrastran), teniendo como una de las opciones cuando se visualizan nuestros datos el poder diferenciarlos por colores arrastrando dentro de «Mark» en donde indica «color» por ejemplo la columna de datos «species» y también lo podemos dividirlos en files o columnas si arrastramos los mismos datos dentro de donde indica «Facet«.

Vista de gráficos empleando opciones de marcas y facetas.

Otra opción que podemos apreciar es la posibilidad de incorporar algunos filtros, como ejemplo arrastramos una columna de datos numéricos con la finalidad de reducir los valores a un rango específico de valores, con la finalidad de ajustar nuestro gráfico. Como se aprecia en la figura siguiente, se elimina valores de una especie que esta fuera del rango establecido por el filtro.

Uso de nuestro datos

Ahora nos toca usar los datos que fueron descargados de la fuente ya mencionada. Seguiremos el mismo procedimiento seguido con la diferencia que debemos agregar el paso previo de leer datos en formato CSV, empleando el paquete CSVFiles.jl, luego con el paquete DataFrames.jl generar nuestra estructura de datos bajo el esquema de los Dataframes.

crop_data = load("voyager/data/crop_production.csv") |>DataFrame

v = crop_data |> Voyager()
Vista de nuestros datos dentro de DataVoyager

Luego de ajustar nuestras columnas de datos empleando las opciones que tenemos dentro de esta herramienta, vamos a generar un gráfico que será mostrado en nuestra vista específica. Finalmente si estamos conforme con el resultado, es obvio que necesitamos exportarlo a un formato de imagen por lo general para que puede ser incluido en quizás alguna presentación que necesitamos realizar. Para ello podemos seguir las indicaciones del siguiente código en Julia.

plot1 = v[]

plot1 |> save("voyager/output/prod_media.svg")

Si bien podemos exportarlo a otros formatos como *.png, se recomienda emplear el formato *.svg, con la finalidad de tener una mejor presentación sin alteración en la calidad de la imagen.

Reflexión Final

Siempre considero importante tener la posibilidad de explorar nuestros datos de manera rápida, ahora conocemos una herramienta que nos permite realizarlo de manera interactiva y de manera muy «visual», generando gráficos de manera rápida y de manera intuitiva, aunque es verdad que estamos limitados en el conocimiento más profundo de los datos, sobre todo desde el lado de la calidad de los mismos, es decir, a primera vista no podríamos darnos cuenta si existen datos faltantes por ejemplo. En general considero que esta herramienta podría ser muy útil para datos que de antemano conocemos que son confiables y necesitamos mostrar gráficos para una presentación rápida. Mientras exploraba la herramienta, me pude dar cuenta que la aplicación propia del mismo Voyager, presenta mayores opciones, les recomiendo probarla y si quieren profundizar también pueden revisar su documentación que es muy completa sobre todo lo que podríamos realizar con esta herramienta. También logre encontrar un paper sobre el mismo.

Bueno, espero que la herramienta presentada sea de mucha utilidad al momento de hacer una exploración inicial de sus datos. De la misma manera se ha elaborado un video sobre el uso de esta herramienta para que puedan ver con mayor detalle las opciones que fueron empleadas.