---
{
  "title": "Navegando los datos de Terminology en FHIR: Perspectivas y desafíos",
  "description": "Nos centramos en el registro de IG de FHIR, ya que ofrece un conjunto de datos exhaustivo. Con ello, buscamos identificar los problemas, desafíos y casos de uso más urgentes que probablemente encontraríamos.",
  "date": "2024-07-08",
  "author": "Orlando Osorio",
  "reading-time": "12 min read",
  "tags": [
    "Terminology",
    "FHIR Standard"
  ]
}
---

> For the complete documentation index, see [llms.txt](https://www.health-samurai.io/llms.txt).
> Use it to discover all available pages before guessing URLs.

---
### Introducción
Cuando nos propusimos construir una solución de [Terminology](/blog/introducing-hybrid-terminology-engine) para Aidbox y comenzamos a trabajar en el proyecto Babylon, decidimos examinar más de cerca el estado de los datos de Terminology dentro de la comunidad FHIR. Nos centramos en el [registro de IG de FHIR](/articles/how-to-build-ig), ya que ofrece un conjunto de datos exhaustivo. Con ello, buscamos identificar los problemas, desafíos y casos de uso más urgentes que probablemente encontraríamos. Este artículo presenta nuestros hallazgos, incluidos aspectos generales, problemas de calidad de datos, patrones específicos observados en el conjunto de datos y desafíos encontrados durante la implementación.

Como fuente de datos, utilizamos el [servidor de paquetes FHIR](https://packages2.fhir.org/packages/catalog) [[1](#Appendix)]. Descargamos todos los paquetes disponibles, extrajimos los recursos relacionados con Terminology [[2](#Appendix)] y los cargamos en una base de datos Postgres. Para la visualización, creamos paneles en Grafana, que se incluyen en el apéndice. Este análisis se realizó el 14 de junio de 2024.

### Perspectivas
**Algunos números**

Descargamos **2.357** paquetes distintos del registro, que representan **468** nombres de paquetes únicos con sus versiones. Como se muestra en la Fig. 1 (nótese que utilizamos escala logarítmica), el paquete con mayor número de recursos de Terminology fue, con diferencia, *us.nlm.vsac*, compuesto principalmente por ValueSets; seguido de *hl7.terminology.** y *hl7.fhir.**.
![](image-1.avif)*      Fig 1. Los 20 paquetes con más recursos (escala logarítmica)        *
Tras cargar los recursos, encontramos **75,8K** recursos CodeSystem, con **6,36K** URLs canónicas únicas. De estos, pudimos extraer **15** millones de conceptos individuales, de los cuales **3,89** millones son únicos [[3](#Appendix)]. Además, cargamos **454K** recursos ValueSet, de los que **33,7K** son únicos.

La mayoría de los recursos no tienen nombre de publicador; entre los que sí lo tienen, HL7 es el principal, aunque la nomenclatura no siempre es coherente (véase la Fig. 2).
![](image-2.avif)*Fig 2. Los 20 principales publicadores*
Al analizar la publicación de nuevos recursos a lo largo de los años [[4](#Appendix)] (Fig. 3), observamos un pico de nuevos recursos en 2014, que coincide con DSTU 1.
![](image-3.avif)*Fig 3. Recursos a lo largo de los años*
Observando los principales publicadores en el tiempo (Fig. 4):
![](image-4.avif)*Fig 4. Cuota de los principales publicadores a lo largo de los años*
#### Problemas de calidad de datos
Nuestro análisis de los datos de [Terminology de FHIR](/blog/two-phase-fhir-terminology) reveló varios problemas de calidad que podrían afectar a la usabilidad y fiabilidad de estos recursos. Estos problemas dificultan que los implementadores puedan dar soporte de forma fiable a operaciones como validación, búsqueda, expansión, etc. A continuación, describimos algunos de los principales problemas encontrados.

#### Recursos inválidos
Uno de los desafíos al cargar los recursos fue que, en ocasiones, estos no se ajustaban a la especificación base de FHIR; por ejemplo, faltaban campos obligatorios, había tipos de datos inválidos o se incumplían restricciones. Algunos de estos problemas se corrigen en versiones posteriores de los paquetes, pero otros siguen siendo inválidos en las versiones más recientes.
![](image-5.avif)
En algunos casos, estos problemas hacen casi imposible cargar los datos por completo, ya que no parece existir una estrategia o solución alternativa para gestionar estos recursos. En algunos [casos extremos](https://simplifier.net/packages/ca.on.ppr.r4/1.2.0/files/2360389/~json) solo obtenemos una lista de conceptos y nada más; en otros, como los códigos nulos, simplemente no existe un valor de reserva [[5](#Appendix)].

También identificamos otra categoría de problemas. Aunque no harían que un recurso fuera inválido o no conforme a las restricciones, sí representarían un problema desde el punto de vista de la implementación. En concreto, encontramos sistemas de códigos con URLs malformadas. Afortunadamente, en la versión más reciente de los paquetes, solo queda uno de estos casos [[6](#Appendix)].

#### Duplicados y conflictos
En ocasiones, el mismo recurso se publica en diferentes versiones del mismo paquete. En otros casos, el recurso se traslada a un paquete distinto, pero la versión se mantiene igual. Estos escenarios no deberían ser problemáticos siempre que el recurso no cambie, pero esto no siempre ocurre, especialmente cuando los cambios son contradictorios [[7](#Appendix)].

Los tipos de conflicto con mayor impacto aparecen en los conceptos, ya que representan el contenido real del sistema de códigos. Con frecuencia cargamos dos conceptos provenientes del mismo sistema de códigos lógico (mismo `url` y `version`), que tienen un `code` coincidente pero cuyos `display, definition` o `property` no coinciden.

Una posible estrategia es confiar siempre en los cambios más recientes, pero esto no siempre funciona; como ejemplo, podemos observar `eng.fhir.profile.dev`, donde de la versión `0.0.4-beta` a la `0.0.7-beta` uno de los displays se cambió así:

- Oscuramento del oscuramento

+ Oscuramento del documento

Aparentemente, una regresión en la corrección de una errata.

Es habitual encontrar sistemas de códigos en conflicto donde los conceptos con propiedades diferentes no representan conflictos de contenido, sino conflictos de presentación (es decir, conservan la semántica pero cambia la sintaxis). Algunos de los casos más comunes son los siguientes:

- cambio de tipo de dato, p. ej., `valueString` a `valueCode`.
- cambio de configuración regional, p. ej., `valueDateTime: "2009-08-20"` a `valueDateTime:     "2009-08-20T00:00:00-04:00"`

En ocasiones, un CodeSystem puede tener dos conceptos con el mismo código, violando así [csd-1](https://www.hl7.org/fhir/codesystem.html#invs). Esto sería un simple error de datos si se tratara de una duplicación por equivocación, pero estos códigos podrían representar conceptos semánticamente distintos, lo que agrava considerablemente el problema.

#### Conflictos semánticos: ISO-3166 (Códigos de país)
Puede darse un CodeSystem con conceptos que comparten un código pero representan esencialmente conceptos distintos; esto es especialmente problemático para la implementación, ya que la unicidad semántica de los conceptos es uno de los axiomas fundamentales de [Terminology en FHIR](/articles/two-phase-fhir-terminology).

Tomemos como ejemplo [ISO-3166](https://www.iso.org/iso-3166-country-codes.html) (urn:iso:std:iso:3166|57): el CodeSystem cargado desde [`fhir.tx.support.r4`](https://simplifier.net/packages/fhir.tx.support.r4/0.18.0/~files) hasta la versión `0.18.0` contenía una lista de conceptos de ISO-3166 que mezclaba códigos Alfa-2, Alfa-3 y Numéricos como `code` de los conceptos, añadiendo una propiedad `canonical` con el código Alfa-2.

Ahora bien, para algunos países que han cambiado de nombre (p. ej., Birmania a Myanmar, Zaire a RDC, Yugoslavia a Serbia y Montenegro, etc.), el código numérico se mantiene y solo cambian los códigos Alfa. Por tanto, representan dos conceptos distintos en ISO-3166 pero tienen el mismo código en el recurso FHIR.

#### Algunos números más
En esta sección exploramos los aspectos cuantitativos del conjunto de datos de Terminology de FHIR, examinando totales, distribuciones y patrones.

#### Sistemas de códigos
En la Fig. 5 podemos ver que, entre los sistemas de códigos que enumeran explícitamente sus conceptos, la mayoría de los más grandes son compendios de datos geográficos; el mayor de ellos es el de códigos postales de Quebec, con más de **200.000** conceptos, seguido de varias versiones de ICD10.
![](image-6.avif)*Fig 5. Los 20 sistemas de códigos más grandes*
En términos de popularidad, el sistema de códigos más referenciado es, como cabría esperar, SNOMED. Tras SNOMED, otros sistemas frecuentemente referenciados incluyen LOINC, ICD10, ICD9, RxNorm, DICOM y CPT (véase la Fig. 6).
![](image-7.avif)*Fig 6. Sistemas de códigos más referenciados*
En la Fig. 7 podemos ver que la mayoría de los sistemas de códigos incluyen explícitamente todos sus conceptos en el recurso [[8](#Appendix)]. Solo 41 son suplementos; aunque esto parece una forma muy útil de ampliar los conceptos existentes, no está muy extendida y la mayoría son traducciones [[9](#Appendix)].
![](image-8.avif)*Fig 7. Desglose del contenido de los sistemas de códigos*
#### Value Sets
Al analizar los value sets, su aspecto más interesante es, sin duda, sus reglas de `compose`. Clasificamos los value sets en 5 categorías principales [[10](#Appendix)]:
- **Extensional**: Enumeración explícita de conceptos
- **Intensional (copia)**: Copia de un sistema de códigos o value set existente
- **Intensional (filtro)**: Definido algorítmicamente a partir de reglas de selección sobre un sistema de códigos existente
- **Mixto**: Combinación de las técnicas anteriores
- **Sin Compose**: el campo `compose` no está presente

Curiosamente, la mayoría (más del **60**%) se clasifican como extensionales y solo el **10**% utilizan las capacidades de filtrado de los ValueSet (véase la Fig. 8).
![](image-9.avif)*Fig 8. Clasificación de los value sets por Compose*
Aunque la mayoría de los value sets no están expandidos (véase la Fig. 9), casi el **40**% aparecen pre-expandidos en sus paquetes.
![](image-10.avif)*Fig 9. Desglose de la expansión de ValueSet*
#### Análisis de filtros
FHIR [proporciona](https://build.fhir.org/valueset.html#compositions) un mecanismo potente y extensible para definir criterios de selección que permiten definir value sets algorítmicamente a partir de sistemas de códigos existentes. La herramienta principal para expresar estas reglas son los [filtros](https://build.fhir.org/valueset.html#filters).

**Sobre `valueset-rules-text` y `valueset-expression`**

Aunque los value sets pueden definirse de [dos formas adicionales](https://build.fhir.org/valueset.html#compose), solo una de ellas se utiliza realmente, además de en recursos de ejemplo.

- **`valueset-expression`**
[...] Una expresión que proporciona una definición alternativa del contenido del value set [[11](#Appendix)]

- **`valueset-rules-text`**
[...] instrucciones que solo podría seguir un ser humano. [[12](#Appendix)]

Esto es posiblemente una buena noticia para los implementadores, ya que las otras dos opciones parecen presentar desafíos para la interoperabilidad.

Los value sets pueden utilizar el conjunto de [filtros base](https://build.fhir.org/codesystem.html#filters) definidos para todos los sistemas de códigos, así como cualquier filtro adicional definido en `CodeSystem.filter`. En la Fig. 10 podemos ver que la combinación `filter + op` más utilizada es, como era de esperar, `concept is-a`, ya que es una forma sencilla de aprovechar la naturaleza jerárquica de muchas terminologías.
![](image-11.avif)*Fig 10. Propiedad + op por uso*
#### Sistemas de códigos populares
También analizamos algunos de los sistemas de códigos más populares para encontrar perspectivas sobre patrones y casos de uso. En la Fig. 11 podemos ver una comparación de totales; nótese que utilizamos escala logarítmica [[13](#Appendix)].
![](image-12.avif)*Fig 11. Comparación de totales de sistemas de códigos populares*
Para muchos de estos sistemas de códigos no es práctico enumerar sus conceptos explícitamente en la definición del recurso, por eso la mayoría solo indican `not-present` y corresponde al implementador proporcionar una fuente indexada para atender las solicitudes. En la Fig. 12 podemos ver que los únicos sistemas de códigos `complete` son ICD-10 y DICOM (SNOMED aparece en el gráfico como `complete` pero en realidad no lo está; es un error en algunos recursos CodeSystem).
![](image-13.avif)*Fig 12. Desglose del contenido de los sistemas de códigos populares*
#### Filtros
La Fig. 13 muestra una comparación del uso de filtros personalizados frente a los filtros base predefinidos de FHIR, como el ECL de SNOMED. También se muestra una comparación de las expresiones, usando naranja para los filtros personalizados. Podemos observar que la gran mayoría de las expresiones utilizan los filtros base de FHIR, aunque algunos de estos sistemas ofrecen una ontología propia con semántica potente y, en el caso de SNOMED, un lenguaje de consulta maduro.
![](image-14.avif)*Fig 13. Análisis de filtros de los sistemas de códigos populares*
#### Erratas tipográficas
Al analizar estos sistemas de códigos, encontramos que algunos value sets tenían erratas o errores sutiles en la definición de la URL canónica, lo que puede provocar errores inesperados al utilizar dichos value sets. Algunos de estos errores siguen apareciendo en las versiones más recientes de ciertos paquetes.

#### Algunos ejemplos
- http://snomed.info/sct - nótese el espacio en blanco inicial

- http://snomed.info/sct/731000124108

- snomed-ct

- https://loinc.org - https en lugar de http

- http://loinc.org/ - barra inclinada final

#### SNOMED srt
Inicialmente, los códigos DICOM estaban listados en el paquete *fhir.tx.support*. La URL canónica de SNOMED utilizada en esos casos era *http://snomed.info/srt* (srt en lugar de sct). Una vez que se trasladaron al paquete *fhir.dicom*, la URL fue corregida.

Para profundizar en Terminology de FHIR y probar sus capacidades, puede instalar la [versión gratuita de Aidbox](https://www.health-samurai.io/aidbox#run). Esta le permite explorar y experimentar con estos avances en un entorno completamente funcional, ideal para el desarrollo y las pruebas.

#### Apéndice

1. [Packages2](https://packages2.fhir.org/packages/catalog) y [Simplifier](https://simplifier.net/) están sincronizados; en ocasiones utilizaremos URLs de Simplifier para enlazar a un paquete, ya que ofrece una interfaz para visualizar su contenido.
2. CodeSystem, ValueSet y ConceptMap
3. Consideramos que la unicidad de un concepto viene determinada por su sistema, código y versión
4. Existe un recurso publicado en 2161, que probablemente sea una errata o quizás un futuro ValueSet; está publicado por la Federación Unida de Planetas y contiene los cuadrantes de la Vía Láctea.
5. En algunos de estos casos, parece que los autores utilizan conceptos de marcador de posición para la agrupación y no disponen de un valor adecuado para usar como código del indicador de grupo.
6. ValueSet HealthCareProviderTaxonomy del paquete [hl7.fhir.us.directory-attestation](https://simplifier.net/packages/hl7.fhir.us.directory-attestation/)
7. Cambios que eliminan información en lugar de añadirla.
8. Esto no siempre es así; algunos sistemas de códigos tienen content = complete pero no incluyen ningún concepto. Véase la tabla 1.
9. De los que analizamos, parece que todos son traducciones a distintos idiomas.
10. Intensional y Extensional provienen de la [definición estándar de FHIR](https://www.hl7.org/fhir/valueset.html#int-ext)
11. [https://build.fhir.org/ig/HL7/fhir-extensions/StructureDefinition-valueset-expression.html](https://build.fhir.org/ig/HL7/fhir-extensions/StructureDefinition-valueset-expression.html)
12. [https://build.fhir.org/ig/HL7/fhir-extensions/StructureDefinition-valueset-rules-text.html](https://build.fhir.org/ig/HL7/fhir-extensions/StructureDefinition-valueset-rules-text.html)
13. Para visualizar recuentos muy distintos en un mismo gráfico, utilizamos una escala log_10; esto puede llevar a confusión, ya que las diferencias entre valores altos no son tan pronunciadas visualmente como en los datos, especialmente en comparación con los totales más pequeños.