The NA (Numeric Array) data type carries a variable-length sequence of NM values separated by component delimiters (^). It was introduced in v2.3 to carry waveform sample arrays — ECG strips, vital-signs trend buffers, pulse-oximetry plethysmograph traces — and any other observation result whose value is naturally a vector of numbers rather than a single scalar. NA is used in OBX-5 when OBX-2 is NA.
Purpose
NA exists so a multi-sample numeric result can be carried in a single OBX without exploding into one OBX per sample. A 250-sample ECG snippet at 250 Hz is one second of signal; without NA it would require 250 OBX repetitions and a parent-child structure to bind them together. NA collapses the same data into one OBX-5 with 250 components, and the sampling period, scaling factor, and origin offset are carried in the surrounding OBX context (typically OBX-6 Units, OBX-7 References Range, and site-specific extensions) rather than in NA itself.
Component table
Source: HAPI HL7v2 v2.8.1 javadocs (NA). NA is a variable-repeating composite with no fixed component count — each component is an NM numeric value.
| Comp | Name | Sub-type | Length | Required | Description |
|---|---|---|---|---|---|
| NA.1 | Value 1 | nm | — | R | First numeric sample. |
| NA.2 | Value 2 | nm | — | O | Second numeric sample. |
| NA.3 | Value 3 | nm | — | O | Third numeric sample. |
| NA.n | Value n | nm | — | O | n-th numeric sample. NA is open-ended; components continue until end of field. |
There is no upper bound on the number of components — the practical limit is the engine's field-length tolerance.
Most-used components
NA does not have "more important" components — every component is a sample of the same physical quantity and they are interpreted positionally. The interesting metadata lives outside NA:
- OBX-6 Units — the unit of each sample (e.g.
mV,bpm,%). - Parent OBX or sibling OBX — sampling period (Hz or seconds-between-samples) and origin timestamp.
- OBX-7 References Range — valid range for any single sample.
Where it's used
NA is found wherever OBX-2 is NA:
- ECG and other waveform results in cardiology and ICU monitoring feeds.
- Continuous pulse-oximetry, capnography, and arterial-line pressure traces.
- Multi-sample lab buffers (e.g. spectrophotometer absorbance arrays).
- Custom Z-segments that carry trend buffers from medical-device gateways.
Less commonly, NA shows up in MFA/MFR responses that carry tabular numeric extracts.
Version differences
- v2.1 / v2.2 — NA did not exist. Vector results were modeled as repeating OBX with a sub-identifier or as packed strings.
- v2.3 — NA introduced. OBX-2 gains
NAas a value-type code. - v2.4 – v2.8.1 — NA structure unchanged. The standard does not impose a component count limit; engines impose their own.
Common mistakes
- Mixing units inside a single NA. Every component must share the unit declared in OBX-6. A field that alternates
temp^pulse^temp^pulseis malformed — use two separate OBX rows. - Embedding empty components for missing samples.
120^^121^^122collapses to120,121,122for some parsers and to120,null,121,null,122for others. Use a sentinel value (often-32768or a documented placeholder) or split the array around the gap. - Carrying the sampling period inside NA. NA only carries samples. Period belongs in OBX-6 or a sibling OBX, never as a prefix component.
- Exceeding receiver field-length limits. A 10-second ECG at 500 Hz is 5,000 components and several tens of KB once formatted. Some MLLP receivers reject fields above 65 KB.
- Confusing NA with SN Structured Numeric. SN carries a single numeric with a comparator and optional range; NA carries many numerics with no comparator.
Examples
Minimal value — 5-sample SpO2 window
98^97^98^99^98
Five percent-saturation samples, one per second, with the unit % declared in OBX-6 and the period implicit.
Multi-component — short heart-rate trend buffer
120.5^121.2^119.8^120.1^120.9
Five floating-point bpm values.
In-context excerpt — ECG waveform OBX
OBX|1|NA|MDC_ECG_LEAD_II^ECG Lead II^MDC||-0.012^-0.008^0.001^0.014^0.027^0.041^0.052^0.058^0.054^0.041^0.022^0.001^-0.018^-0.029^-0.032^-0.028^-0.019^-0.008^0.003^0.012|mV|||||F
OBX|2|NM|MDC_ECG_LEAD_II_SAMPLE_RATE^Sample Rate^MDC||500|Hz|||||F
OBX-1 carries 20 samples of ECG Lead II as NA. OBX-2 carries the sample rate (500 Hz) as a sibling NM result, telling the receiver that the 20 samples in OBX-1 span 40 ms.
Common pitfall — empty components for missing samples
120.5^121.2^^^^120.9
Four missing samples between sample 2 and sample 5. Receivers handle this inconsistently — some emit null for each gap, others collapse the empty components. If gap representation matters, document the convention in the integration profile.
FHIR mapping
The v2-to-FHIR Implementation Guide publishes ConceptMap-datatype-na-to-sampleddata. NA's component values map to SampledData.data as a space-separated string of numerics. The surrounding OBX context — sampling period, scaling factor, origin — must be lifted into SampledData.period, SampledData.factor, and SampledData.origin because NA itself carries none of these.
| NA component(s) | FHIR element |
|---|---|
| NA.1 … NA.n | SampledData.data (space-separated numerics) |
| (count of components) | SampledData.dimensions (typically 1 for single-channel NA) |
| (from sibling OBX) | SampledData.period (ms between samples) |
| (from OBX-6 Units) | Observation.valueSampledData carried inside Observation with the unit on the parent code |
| (from parent OBX timestamp) | SampledData.origin |
Engine considerations
- Field length. Long NA fields stress MLLP parsers. Engines should publish their field-length limit and route waveform feeds through paths sized for it (often a dedicated channel).
- Numeric precision. NA values are NM, so signed decimals with optional exponent are valid. Engines must preserve the source precision — truncating
0.0125to0.01corrupts the waveform. - Sample gap convention. Define and document whether empty components mean "missing sample" or "skip" before the integration goes live. Vorro defaults to "missing sample = null in canonical model".
- Period/origin out-of-band. The sampling period and origin timestamp are not in NA. Engines mapping to SampledData must source them from a sibling OBX or a profile constant.
- HAPI accessor. HAPI v2.8.1 exposes NA as
ca.uhn.hl7v2.model.v281.datatype.NA; samples are read viagetValue1(),getValue2(), … or as a flat array.
How Vorro parses and produces NA
Vorro's HL7 parser reads NA into a typed double[] on its canonical observation model and tags the array with the unit from OBX-6 and the sampling period from whichever sibling OBX or profile constant the route's mapping specifies. Empty components are parsed as NaN and surfaced as null in the canonical model; engines downstream can choose to interpolate, drop, or flag the gaps.
On outbound, Vorro emits NA when a route's profile declares OBX-2 as NA. The numeric formatter respects the source precision (no silent rounding) and emits up to a configurable per-route component count (default 5,000) before splitting the array across multiple OBX rows with an OG-style sub-identifier to bind them. Sampling period is always emitted as a sibling NM observation, never as an NA prefix.
