Slot: Null-Semantics Column (null_semantics_column)
Name of a per-value column carrying a null-semantics indicator drawn from NullSemanticsEnum (present / structural_null / derived_null / true_zero; see envar_common). Bound here in DataLayout — mirroring the existing per-value value_uncertainty_column / quality_flag_column pattern — because the distinction is per-value: whether a given blank or 0 means "no source data", "aggregation impossible", or "measured zero" varies row by row and so must be carried alongside the values, not declared once for the dataset. Null with reason when the producer does not distinguish null kinds. The vocabulary itself lives in the Uncertainty / shared layer (NullSemanticsEnum).
Tier: recommended
Why this slot matters
A blank or a 0 is ambiguous, and the three kinds of "missing/zero" have OPPOSITE correct handling — structural_null and derived_null must be dropped (the latter also excluded from denominators) while true_zero must be kept as a real zero; conflating them biases the health-effect estimate. Nulls should be excluded from percentile denominators for exactly this reason, so binding a per-value null-kind column is what lets a consumer handle each cell correctly instead of reading missingness as low or zero exposure.
In plain terms
A blank cell or a 0 can mean three very different things: there was never any data here, we could not compute a value here, or the value is genuinely zero. Each needs different treatment. This names the column that tags every value with which kind it is, so nobody mistakes "no data" for "zero exposure".
URI: envar:slot/null_semantics_column
Applicable Classes
| Name |
Description |
Modifies Slot |
| DataLayout |
How the companion data file (CSV / parquet) is laid out and how this record's... |
no |
Properties
Type and Range
Cardinality and Requirements
Examples
Annotations
| property |
value |
| tier |
recommended |
| justification |
A blank or a 0 is ambiguous, and the three kinds of "missing/zero" have OPPOSITE correct handling — structural_null and derived_null must be dropped (the latter also excluded from denominators) while true_zero must be kept as a real zero; conflating them biases the health-effect estimate. Nulls should be excluded from percentile denominators for exactly this reason, so binding a per-value null-kind column is what lets a consumer handle each cell correctly instead of reading missingness as low or zero exposure. |
| explanation |
A blank cell or a 0 can mean three very different things: there was never any data here, we could not compute a value here, or the value is genuinely zero. Each needs different treatment. This names the column that tags every value with which kind it is, so nobody mistakes "no data" for "zero exposure". |
| covered_by |
None |
Schema Source
Mappings
| Mapping Type |
Mapped Value |
| self |
envar:null_semantics_column |
| native |
envar:null_semantics_column |
LinkML Source
name: null_semantics_column
annotations:
tier:
tag: tier
value: recommended
justification:
tag: justification
value: A blank or a `0` is ambiguous, and the three kinds of "missing/zero" have
OPPOSITE correct handling — structural_null and derived_null must be dropped
(the latter also excluded from denominators) while true_zero must be kept as
a real zero; conflating them biases the health-effect estimate. Nulls should
be excluded from percentile denominators for exactly this reason, so binding
a per-value null-kind column is what lets a consumer handle each cell correctly
instead of reading missingness as low or zero exposure.
explanation:
tag: explanation
value: 'A blank cell or a `0` can mean three very different things: there was
never any data here, we could not compute a value here, or the value is genuinely
zero. Each needs different treatment. This names the column that tags every
value with which kind it is, so nobody mistakes "no data" for "zero exposure".'
covered_by:
tag: covered_by
annotations:
omop_gaia:
tag: omop_gaia
annotations:
extent:
tag: extent
value: partial
status:
tag: status
value: asserted
where:
tag: where
value: gaia_catalog meta_etl_*.json nodata = ["float4", "-9999"] (dataset-level
sentinel, not per-value null-kind)
note:
tag: note
value: 'GAIA declares a dataset-level nodata sentinel for daymet but no
per-value column tagging present / structural_null / derived_null /
true_zero. Conservative: partial.'
degauss:
tag: degauss
annotations:
extent:
tag: extent
value: absent
status:
tag: status
value: asserted
where:
tag: where
value: no column
note:
tag: note
value: DeGAUSS emits no null-kind indicator column and no missing-value
sentinel in its CSV output.
amadeus:
tag: amadeus
annotations:
extent:
tag: extent
value: partial
status:
tag: status
value: asserted
where:
tag: where
value: thredds_dataset.xml _FillValue / missing_value = 32767 (dataset-level
sentinel, not per-value null-kind)
note:
tag: note
value: 'Amadeus declares a fill/missing-value sentinel that marks structural
nulls, but no per-value column distinguishing the three null kinds.
Conservative: partial.'
cher:
tag: cher
annotations:
extent:
tag: extent
value: absent
status:
tag: status
value: asserted
where:
tag: where
value: no column
note:
tag: note
value: C-HER handles null semantics in its validation rules, but binds
no per-value null-kind column in table_column_dictionary.
codata:
tag: codata
annotations:
extent:
tag: extent
value: out_of_layer
status:
tag: status
value: asserted
where:
tag: where
value: no column
note:
tag: note
value: A per-value null-semantics column binding is instance-layer layout,
outside CODATA's conceptual scope.
description: 'Name of a per-value column carrying a null-semantics indicator drawn
from `NullSemanticsEnum` (`present` / `structural_null` / `derived_null` / `true_zero`;
see envar_common). Bound here in `DataLayout` — mirroring the existing per-value
`value_uncertainty_column` / `quality_flag_column` pattern — because the distinction
is per-value: whether a given blank or `0` means "no source data", "aggregation
impossible", or "measured zero" varies row by row and so must be carried alongside
the values, not declared once for the dataset. Null with reason when the producer
does not distinguish null kinds. The vocabulary itself lives in the Uncertainty
/ shared layer (`NullSemanticsEnum`).'
title: Null-Semantics Column
examples:
- value: null_kind
description: per-value column tagging each cell present / structural_null / derived_null
/ true_zero, next to the value column
from_schema: https://w3id.org/linkml/microschemas/envar
rank: 1000
domain_of:
- DataLayout
range: string