Cómo Convertir un Bundle FHIR a CSV Sin Perder Datos
Hl7 Tools

Cómo Convertir un Bundle FHIR a CSV Sin Perder Datos

Por Qué "Expórtalo a CSV" No Es Tan Sencillo

Alguien te pasa un Bundle FHIR y te pide una hoja de cálculo. Suena a cinco minutos de trabajo. Abres el fichero y te encuentras un documento JSON con un array entry que contiene cuarenta recursos de nueve tipos distintos, cada uno un árbol anidado con arrays dentro de objetos dentro de arrays. Ahí no hay ninguna tabla evidente, y ese es exactamente el problema. FHIR es un grafo de recursos tipados y anidados; CSV es un rectángulo plano de filas y columnas. Pasar de uno a otro no es un cambio de formato: es una decisión de modelado, y la calidad de tu hoja depende por completo de las decisiones que tomes por el camino.

Esta guía recorre esas decisiones en el orden en que aparecen: separar el bundle por tipo de recurso, decidir qué hacer con los valores repetidos, elegir columnas y, por último, abrir el resultado en Excel sin corromperlo en silencio. Puedes seguirla con el Explorador de Bundles FHIR, que aplana en tu navegador y no sube el fichero a ningún sitio. Si todavía no tienes claro qué es un Bundle y qué contienen sus entradas, empieza por Qué Es un Bundle FHIR y vuelve luego.

Decisión Uno: Una Tabla por Tipo de Recurso

El primer impulso —una fila por cada entrada del bundle— produce una tabla inservible. Un Patient tiene birthDate y gender; una Observation tiene valueQuantity y effectiveDateTime; un MedicationRequest tiene intent y dosageInstruction. Si los metes todos en la misma hoja obtienes una rejilla dispersa donde cada fila usa una décima parte distinta de las columnas, y cualquier fórmula que escribas tiene que filtrar por tipo antes de poder calcular nada.

El modelo que funciona es una tabla por resourceType. Un bundle con 12 Patients, 340 Observations y 28 Conditions se convierte en tres tablas con tres juegos de columnas, y cada una es analizable de inmediato: puedes promediar las Observations, contar las Conditions y volver a unirlas con los Patients por la referencia al sujeto. Por eso el Explorador empieza contando recursos por tipo y te hace elegir el tipo antes de dibujar la tabla: el tipo es el esquema.

Esto implica también que un bundle suele dar varios CSV, no uno. No es una limitación de la herramienta, es la forma honesta de los datos. Resiste la tentación de forzar la unión en el momento de exportar. Exporta las tablas por separado y únelas después en la herramienta que vaya a hacer el análisis, donde controlas la semántica del join.

Decisión Dos: Qué Pasa con los Valores Repetidos

Aquí es donde la mayoría de los conversores ingenuos pierden datos. FHIR está lleno de elementos repetibles. Un Patient puede tener varios name y cada nombre varios given. Una Observation puede llevar varios identifier, varios performer, varias category. Una celda CSV guarda una sola cadena. Algo tiene que ceder.

El primer paso es decidir qué significa "columna" cuando hay arrays por medio. Si indexas cada posición —name[0].given[0], name[1].given[0], name[1].given[1]— acabas con una tabla cuyo juego de columnas cambia según qué paciente tenga más nombres compuestos. Eso es inutilizable: añadir un registro ensancha la hoja. La alternativa, y lo que hace el Explorador, es eliminar los índices de array de la ruta. Tanto name[0].given[0] como name[1].given[1] colapsan en la ruta única name.given. Todos los valores que pertenecen al mismo campo conceptual caen en la misma columna, y el juego de columnas es estable sin importar cuántas repeticiones tenga cada registro.

Una vez colapsadas las rutas, una columna puede contener varios valores para un mismo recurso, y tú eliges cómo representarlos.

Modo Unir: Una Fila por Recurso

En modo unir, cada recurso produce exactamente una fila, y los valores repetidos de una celda se concatenan con punto y coma. Una paciente con los nombres "María" y "Elena" muestra María;Elena en la columna given. No se descarta nada, el número de filas coincide con el de recursos y un =CONTARA() sobre la columna de id te dice cuántos pacientes tienes.

Usa el modo unir cuando la hoja sea para leer, conciliar o contar registros: las preguntas cotidianas de "cuántos y cuáles". Su punto débil es la aritmética: una celda con 72;68;75 es texto, no tres números, así que no puedes promediarla sin volver a separarla.

Modo Expandir: Una Fila por Repetición

En modo expandir, un recurso con valores repetidos produce varias filas: tantas como valores tenga su columna multivaluada más ancha. Cada fila toma el valor i-ésimo de cada columna multivaluada, y las columnas de un solo valor se repiten hacia abajo en todas ellas, de modo que cada fila sigue siendo autoexplicativa: el id del paciente, la fecha y el estado aparecen en cada fila expandida en lugar de dejar huecos bajo una cabecera que parece combinada.

Usa el modo expandir cuando los números tengan que ser números: cuando vayas a pivotar, graficar, promediar o alimentar un paquete estadístico que espera datos ordenados con una observación por fila. Su coste es que el número de filas ya no equivale al de recursos, así que contar registros significa contar ids distintos y no filas. Ninguno de los dos modos descarta datos; intercambian una celda apretada por una fila multiplicada, y saber qué intercambio quieres antes de exportar te ahorra repetir la operación.

Decisión Tres: Elegir las Columnas

Una sola Observation puede exponer varias decenas de rutas terminales cuando recorres el árbol entero. Exportarlas todas te da una hoja por la que tienes que desplazarte lateralmente un minuto antes de encontrar la columna del valor, y la mayoría de esas rutas estarán vacías en la mayoría de las filas. Elegir columnas es, por tanto, un acto editorial real, no un valor por defecto.

Tres estrategias cubren casi todos los casos. Hay presets curados para los tipos de recurso que dominan los bundles reales —Patient, Observation, Condition, Encounter, MedicationRequest, Procedure, AllergyIntolerance, Immunization y DiagnosticReport— con los campos que una persona quiere de verdad: para Observation, id, estado, código y descripción, valor y unidad de la cantidad, fecha efectiva y referencia al sujeto. Los presets se filtran contra tus datos reales, así que un bundle cuyos Patients no llevan dirección no muestra una columna de dirección vacía.

Para cualquier tipo sin preset curado, las columnas se derivan de los datos: se cuenta cada ruta terminal entre los recursos de ese tipo y las doce rutas más pobladas se convierten en las columnas. Es una heurística deliberadamente simple, y funciona porque los campos que importan son los que más registros rellenan. Por último, mostrar todas las columnas existe para la exportación de archivo, cuando prefieres tenerlo todo y ocultar columnas después.

Hay elementos que quedan excluidos del aplanado a propósito, y conviene saber por qué para no echarlos de menos. meta guarda contabilidad del servidor —versiones y marcas de última actualización— que no dice nada del paciente. text es la narrativa legible, un bloque XHTML que reventaría cualquier celda y duplica datos estructurados que ya tienes en columnas. extension es arbitraria, específica de cada perfil e irregular en su forma, así que incluirla genera una larga cola de columnas rellenas en un puñado de filas. Si necesitas alguna de esas partes, trata el JSON como fuente de verdad en lugar de forzarlas dentro de una tabla.

Cómo Convertir un Bundle FHIR a CSV Sin Perder Datos

Abrir el CSV en Excel Sin Destrozarlo

Un CSV correcto todavía puede quedar arruinado por la hoja de cálculo que lo abre. Aquí los datos sanitarios sufren más que otros, porque muchísimos de sus campos parecen otra cosa para un autoformateador.

El primer riesgo es la inyección de fórmulas. Las hojas de cálculo tratan una celda que empieza por =, +, - o @ como una fórmula a evaluar en lugar de texto a mostrar. Los campos de texto de FHIR están influidos por el usuario —una nota, un nombre para mostrar, una línea de dirección libre— así que un valor que empiece por uno de esos caracteres puede ejecutarse al abrir. El Explorador lo neutraliza anteponiendo un tabulador a esas celdas antes de entrecomillar, lo que mantiene el texto legible e impide la evaluación. Si construyes tu propio exportador, haz lo mismo: es un control de seguridad real, no un detalle estético.

El segundo riesgo es el autoformato. Un número de historia clínica como 0012345 pierde los ceros a la izquierda. Un identificador numérico largo se convierte en notación científica. Un código que parece una fecha —y los sistemas de codificación clínica están llenos de cosas que parecen fechas— se reescribe en silencio. La costumbre robusta es no hacer doble clic en el fichero. Abre Excel primero y usa Datos → Obtener datos → Desde texto/CSV, y en la vista previa marca el tipo de dato Texto en cada columna de identificadores y códigos antes de cargar. En Google Sheets, usa Archivo → Importar y desactiva "Convertir texto en números, fechas y fórmulas". Son quince segundos que evitan la clase de error en la que una hoja lleva meses estando discretamente mal.

El tercero es el entrecomillado y la codificación. El RFC 4180 es la definición de referencia del formato CSV: los campos que contienen una coma, una comilla doble o un salto de línea deben ir entre comillas dobles, y una comilla interna se escapa duplicándola. El texto clínico libre contiene las tres cosas con regularidad, así que un exportador que solo entrecomilla "cuando parece necesario" acabará emitiendo una fila rota. Entrecomillar todos los campos siempre es más simple y siempre válido. En cuanto a codificación, los nombres de pacientes llevan tildes y caracteres no latinos: el fichero debe ser UTF-8, y si tu versión de Excel sigue leyendo mal el UTF-8 al abrir directamente, la ruta Desde texto/CSV te deja fijar la codificación de forma explícita.

Comprueba la Tabla Antes de Fiarte de Ella

Antes de que el CSV salga a ningún sitio, haz tres comprobaciones rápidas. ¿El número de filas cuadra con lo esperado —el de recursos en modo unir, o algo mayor y explicable en modo expandir—? ¿El recuento de recursos por tipo coincide con lo que el emisor dijo enviar? ¿Y las columnas de referencia, como subject.reference, contienen valores que apuntan de verdad a recursos del mismo bundle? Esto último es el defecto silencioso más habitual en un bundle recibido, y merece entenderse bien: Cómo Funcionan las Referencias en FHIR cubre las referencias relativas, las entradas urn:uuid: y por qué algunas referencias no pueden resolverse localmente.

Conviene además ser explícito sobre lo que una herramienta de aplanado no hace. Lee y reorganiza; no juzga la conformidad. Un recurso al que le falte un elemento obligatorio se aplanará tan tranquilo en una fila con una celda vacía. Si necesitas saber si los datos son válidos contra un perfil, eso es otro trabajo: mira Errores de Cardinalidad y Slicing en FHIR para ver qué detectan realmente esas comprobaciones.

Escala, y Por Qué Aquí Importa Procesar en Local

La conversión es un trabajo iterativo. Exportas, miras la hoja, te das cuenta de que querías otro juego de columnas o el otro modo de repetición, y vuelves a exportar. Cada una de esas pasadas implica información sanitaria protegida real: nombres, fechas de nacimiento, identificadores, diagnósticos. Hacer ese bucle a través de un conversor alojado significa transmitir datos identificables a un tercero en cada iteración, lo que es un problema de RGPD y de HIPAA antes que un problema técnico. Un conversor que corre en el navegador mantiene todo el bucle en tu máquina, y puedes comprobar en la pestaña de red que no sale nada.

Procesar en local impone límites honestos. El Explorador acepta entradas de hasta 25 MB y analiza hasta 20.000 recursos, y cuando alcanza un límite lo dice de forma explícita con el número de recursos descartados, en lugar de truncar tu tabla en silencio. Si tu exportación es mayor, divídela: las exportaciones masivas llegan ya en ficheros separados por tipo de recurso, que es justo la división que quieres. La Exportación Bulk Data de FHIR Explicada cubre cómo llegan esos ficheros y cómo trabajarlos uno a uno.

Conclusión

Convertir FHIR a CSV se reduce a cuatro decisiones tomadas a conciencia: una tabla por tipo de recurso, unir o expandir para los valores repetidos, un juego de columnas elegido según la pregunta que respondes y una ruta de importación a Excel que no convierta tus identificadores en disparates. Colapsa los índices de array para que las columnas sean estables, entrecomilla todos los campos según el RFC 4180, neutraliza los =, +, - y @ iniciales, y revisa las columnas de referencia antes de fiarte del join. Haz todo eso en el navegador con el Explorador de Bundles FHIR y la hoja que entregues sobrevivirá al contacto con un analista de verdad, sin que los datos del paciente hayan salido nunca de tu máquina.

← Volver al Blog