# Cómo normalizar datos médicos

> Tutorial: convierte datos médicos de muchas fuentes en una forma comparable — búsqueda LOINC, unidades UCUM, fechas ISO, rangos de referencia, sin duplicados en reintentos y validación contra el perfil de laboratorio europeo.

Source: https://developers.anpheros.com/es/guides/normalize-medical-data

**Normalizar datos médicos significa convertir valores que llegan en muchas formas a una forma comparable: el mismo código para la misma prueba, el mismo sistema de unidades, fechas en un formato, cada valor con su rango de referencia y su origen, y sin duplicados.** Este tutorial muestra cómo hacer esto antes de que los datos lleguen a un registro HL7 FHIR R4: buscando códigos LOINC y ATC, usando unidades UCUM, rechazando fechas ambiguas, conservando rangos, evitando duplicados en reintentos y verificando el resultado contra el perfil de laboratorio europeo. Cada respuesta mostrada proviene de la API de Anpheros.

## Por qué es importante

El mismo resultado de HbA1c puede llegarle como "HbA1c 6,4 %", "Hemoglobina glicozilada: 6.4", "Glycated haemoglobin 46 mmol/mol" o un código de laboratorio que solo un laboratorio entiende. Hasta que no sean un código con una unidad:

- un gráfico de la HbA1c del paciente a lo largo del tiempo muestra tres líneas no relacionadas;
- una alerta sobre "HbA1c superior al 6,5 %" omite dos de los valores;
- un modelo de IA ve cuatro hechos en lugar de una tendencia;
- otro sistema que recibe el registro no puede interpretarlo.

La normalización pertenece al punto donde los datos entran en el registro, una sola vez, no en cada aplicación que los lee posteriormente.

## Qué tiene un valor normalizado

| Parte | Forma normalizada | Ejemplo |
|---|---|---|
| Qué se midió | un código de un sistema estándar | LOINC `4548-4` (HbA1c), RxNorm `6809` (metformina), ICD-10 `E11` (diabetes tipo 2) |
| El valor | un número, o texto solo cuando el resultado no es numérico | `6.4` |
| La unidad | UCUM | `%`, `mg/dL`, `mm[Hg]`, `kg` |
| Cuándo | una fecha-hora ISO 8601, con zona horaria cuando la hora es importante | `2026-10-01T07:30:00Z` |
| Rango normal | bajo y alto, en la misma unidad | `4.0`–`5.6` |
| Fuente | quién lo produjo y de qué sistema | `import` de `labx` |
| Identidad | algo que hace que una repetición sea reconocible | una clave de idempotencia o un identificador de origen |

Qué sistema de códigos va con qué tipo de recurso se enumera en [Sistemas de códigos FHIR](https://developers.anpheros.com/es/guides/fhir-code-systems).

## Paso 1: encontrar el código

Busque en la terminología de la plataforma por nombre en inglés o rumano, o por abreviatura:

```bash
curl "https://platform.anpheros.com/v1/terminology/loinc?q=hba1c" -H "Authorization: Bearer $KEY"
curl "https://platform.anpheros.com/v1/terminology/loinc?q=hemoglobina%20glicozilata" -H "Authorization: Bearer $KEY"
```

Ambos devuelven el mismo concepto:

```json
{"data": [{"system": "http://loinc.org", "code": "4548-4", "display": "Hemoglobin A1c/Hemoglobin.total in Blood",
           "display_ro": "Hemoglobină glicozilată (HbA1c)", "category": "laboratory", "unit": "%"}], "total": 1}
```

Para medicamentos, [Anpheros Search](https://developers.anpheros.com/es/guides/anpheros-search) encuentra la sustancia por nombre o marca y proporciona su código de ingrediente RxNorm y los números de producto de la EMA:

```bash
curl "https://platform.anpheros.com/v1/search?q=metformin&type=treatment" -H "Authorization: Bearer $KEY"
```

El campo `unit` es la unidad que LOINC espera para esa prueba. Úselo para verificar lo que recibió. Cree el mapeo de los nombres propios de cada fuente a códigos una vez, por fuente, y guárdelo en su integración. No adivine en tiempo de escritura: cuando un nombre es ambiguo y nada en la fuente lo resuelve, déjelo sin mapear y pregunte a la fuente. [Cómo importar resultados de laboratorio a un registro FHIR](https://developers.anpheros.com/es/guides/import-lab-results-fhir) muestra cómo se conservan y reportan los marcadores de laboratorio sin mapear.

## Paso 2: Escribir con códigos, unidades y rangos

```bash
curl -X POST "https://platform.anpheros.com/v1/patients/$PID/observations" -H "Authorization: Bearer $KEY" \
     -H "Content-Type: application/json" -H "Idempotency-Key: lab-77-hba1c" -d '{
  "code": "4548-4", "category": "laboratory",
  "value": 6.4, "unit": "%", "effective_at": "2026-10-01T07:30:00Z",
  "reference_range": {"low": 4.0, "high": 5.6},
  "author_type": "import"
}'
```

```json
{"id": "3296315c-…", "code": "4548-4", "system": "http://loinc.org", "display": "Hemoglobin A1c/Hemoglobin.total in Blood",
 "category": "laboratory", "effective_at": "2026-10-01T07:30:00Z", "value": 6.4, "unit": "%",
 "reference_range": {"low": 4.0, "high": 5.6}, "status": "final", "fhir": "Observation/3296315c-…"}
```

Cuando envías solo el código, la plataforma completa el nombre LOINC estándar, tanto en la API REST como en la API FHIR (`/fhir/R4`), de modo que cada aplicación lee lo mismo `display`. Un `display` que envías tú mismo se mantiene tal cual.

Mantén también la redacción original. Para un informe de laboratorio, `code.text` en la Observación FHIR contiene el nombre del laboratorio ("Hemoglobina glicozilada (HbA1c)") junto a la codificación LOINC. El paciente sigue reconociendo su informe en papel, y no se pierde nada si alguna vez se cuestiona el mapeo.

## Paso 3: Unidades

Utilice códigos UCUM: `mg/dL`, `mmol/L`, `%`, `mm[Hg]`, `kg`, `cm`, `/min`, `Cel`. Dos reglas evitan la mayoría de los errores:

- **No convierta silenciosamente.** Si un laboratorio informa glucosa en `mmol/L` y su aplicación muestra `mg/dL`, almacene lo que midió el laboratorio y convierta al momento de mostrarlo. El valor almacenado permanece rastreable hasta el informe.
- **Verifique la unidad contra el código.** Los códigos LOINC son específicos: HbA1c en `%` es `4548-4`, mientras que HbA1c en `mmol/mol` es un código LOINC diferente. Un valor cuya unidad no coincide con la unidad esperada del código es un error de mapeo, no un problema de conversión.

Anpheros no convierte unidades por usted; almacena la unidad que usted envía.

## Paso 4: fechas

Convierta las fechas a ISO 8601 antes de escribirlas, utilizando el formato conocido de la fuente. `01.10.2026` es el 1 de octubre en Rumanía y muchos países europeos, pero `10/01/2026` es el 1 de octubre solo en los Estados Unidos. La API rechaza cualquier cosa que no sea ISO, en lugar de adivinar:

```json
{"error": {"type": "invalid", "message": "Input should be a valid datetime or date, invalid character in year (at effective_at)", "field": "effective_at"}}
```

El conector de laboratorio es la excepción: acepta `DD.MM.YYYY` y `DD/MM/YYYY` porque sabe que está leyendo un informe europeo.

Para las mediciones donde la hora del día es importante (presión arterial, glucosa, dosis de medicación), envíe la hora con su zona horaria. Una lectura a las 23:30 en Bucarest es del día anterior en UTC, y el paciente espera que esté en el día en que la tomó.

## Paso 5: sin duplicados

Los duplicados provienen de reintentos, del mismo informe enviado dos veces y del mismo valor que llega a través de dos rutas.

- **Reintentos:** envíe un `Idempotency-Key` que identifique el valor en el origen, por ejemplo, el ID del informe y la prueba. Enviar la misma solicitud nuevamente con la misma clave devuelve la primera respuesta y no almacena nada nuevo. Los SDK añaden uno a cada creación.
- **El mismo informe dos veces:** el conector de laboratorio construye un identificador estable por fila a partir del informe, código, fecha y valor, y omite las filas ya importadas.
- **Dos rutas:** almacene el propio ID del sistema de origen con `X-Anpheros-Origin-Id` (o en `identifier` en recursos FHIR), y búsquelo antes de escribir valores que puedan regresar a través de otra ruta.

## Paso 6: Comprobar contra un perfil

Para los resultados de laboratorio, pregunte a la plataforma cómo se compara un recurso con el perfil de informe de laboratorio de HL7 Europe antes de confiar en él:

```bash
curl -X POST "https://platform.anpheros.com/fhir/R4/Observation/\$validate?profile=eu-lab" -H "Authorization: Bearer $KEY" \
     -H "Content-Type: application/fhir+json" -d '{
  "resourceType": "Observation", "status": "final",
  "category": [{"coding": [{"system": "http://terminology.hl7.org/CodeSystem/observation-category", "code": "laboratory"}]}],
  "code": {"text": "HbA1c"}, "subject": {"reference": "Patient/'$PID'"},
  "valueQuantity": {"value": 6.4, "unit": "%"}
}'
```

Este resultado no normalizado obtiene una lista precisa:

```json
{"resourceType": "OperationOutcome", "issue": [
  {"severity": "error", "code": "invalid", "diagnostics": "Observation.code must carry a LOINC coding.", "expression": ["Observation.code"]},
  {"severity": "error", "code": "required", "diagnostics": "Observation.effective[x] is required.", "expression": ["Observation.effective"]},
  {"severity": "warning", "code": "business-rule", "diagnostics": "valueQuantity should carry a UCUM system and code.", "expression": ["Observation.valueQuantity"]},
  {"severity": "warning", "code": "informational", "diagnostics": "No referenceRange: interpretation will need the laboratory's ranges.", "expression": ["Observation.referenceRange"]},
  {"severity": "information", "code": "informational", "diagnostics": "No performer (laboratory) recorded.", "expression": ["Observation.performer"]},
  {"severity": "information", "code": "informational", "diagnostics": "No issued time (when the laboratory released the result).", "expression": ["Observation.issued"]}]}
```

Cada problema se mapea a uno de los pasos anteriores. Ejecute `$validate` en sus pruebas de integración, con muestras reales de cada fuente.

## Paso 7: Mantener el origen

La normalización cambia cómo se escribe un valor, nunca de dónde provino. Envíe `author_type` (`device`, `import`, `practitioner`, `patient`) y `X-Anpheros-Source-System` con cada escritura. Eso es lo que permite a un médico, un auditor o un modelo de IA distinguir un resultado de laboratorio de un valor introducido en casa. Consulte [Explicación de la procedencia de los datos médicos](https://developers.anpheros.com/es/guides/medical-data-provenance).

## Lista de verificación

- [ ] Cada fuente tiene un mapeo de sus nombres a LOINC / ATC / ICD-10, conservado en su integración
- [ ] Los nombres ambiguos permanecen sin mapear y se informan, nunca se adivinan
- [ ] Unidades UCUM, que coinciden con el código; sin conversión silenciosa
- [ ] Fechas ISO 8601, con zonas horarias donde el tiempo es importante
- [ ] Rangos de referencia conservados con valores de laboratorio
- [ ] Redacción original conservada (`code.text`)
- [ ] Claves de idempotencia o IDs de origen en cada escritura
- [ ] `author_type` y sistema de origen en cada escritura
- [ ] `$validate` en pruebas para resultados de laboratorio

## Preguntas frecuentes

### ¿Qué es la normalización de datos médicos?
Convertir datos de salud de diferentes fuentes a una forma estándar: códigos compartidos (LOINC para pruebas y mediciones, ICD-10 para diagnósticos, ATC para medicamentos), unidades UCUM, fechas ISO, rangos de referencia y una fuente registrada, para que los valores de diferentes sistemas puedan compararse, combinarse e intercambiarse.

### ¿Debo convertir todos los valores a una sola unidad?
Almacene la unidad en la que midió la fuente, siempre que sea una unidad UCUM válida que coincida con el código, y convierta al mostrar o analizar. Esto mantiene cada valor almacenado rastreable a su informe original.

### ¿Puede la normalización ser completamente automática?
Mayormente. Los códigos en la fuente, los nombres conocidos y las unidades bien formadas se pueden mapear automáticamente. Los nombres ambiguos y los códigos locales desconocidos necesitan una decisión humana una vez por fuente, después de lo cual el mapeo es automático.

## Relacionado

- [Sistemas de códigos FHIR](https://developers.anpheros.com/es/guides/fhir-code-systems)
- [Cómo importar resultados de laboratorio a un registro FHIR](https://developers.anpheros.com/es/guides/import-lab-results-fhir)
- [Explicación de la procedencia de los datos médicos](https://developers.anpheros.com/es/guides/medical-data-provenance)
- [Interoperabilidad de datos de salud](https://developers.anpheros.com/es/guides/interoperability)
- [API de datos médicos](https://developers.anpheros.com/es/guides/medical-data-api)
