.chain(derived_variables.iter().map(|dv| dv.id.clone()))
.collect(),
));
+ break;
}
}
series
return HashMap::default();
};
+ let markers = if let Some(markers) = graph.interval.footnotes(false)
+ && let Some(series) = series.get(markers.variable.as_str())
+ {
+ Some((
+ series,
+ markers
+ .mappings
+ .iter()
+ .map(|m| (m.from.get(), m.to.as_str()))
+ .collect::<HashMap<_, _>>(),
+ ))
+ } else {
+ None
+ };
+
let mut data = HashMap::new();
let mut coords = Vec::with_capacity(dims.len());
let (cell_formats, format_map) = graph.interval.labeling.decode_format_map(&series);
}
}
}
-
- if let Some(datum) = value.datum()
- && datum.is_sysmis()
- && value.footnotes().is_empty()
+ if let Some((series, mappings)) = &markers
+ && let Some(dv) = series.values.get(i)
+ && let Some(category) = dv.category()
+ && let Some(marker) = mappings.get(&category)
{
- // A system-missing value without a footnote represents an empty cell.
- } else {
+ value.add_subscript(*marker);
+ }
+
+ if !value.is_empty() {
data.insert(coords.clone(), value);
}
}
let cell_footnotes = graph
.interval
- .footnotes()
+ .footnotes(true)
.and_then(|footnotes| series.get(footnotes.variable.as_str()));
let mut data = self.decode_data(graph, &footnotes, cell_footnotes, &dims, &series, warn);
}
impl Interval {
- fn footnotes(&self) -> Option<&Footnotes> {
- if let Some(footnotes) = &self.footnotes {
+ fn footnotes(&self, superscript: bool) -> Option<&Footnotes> {
+ if let Some(footnotes) = &self.footnotes
+ && footnotes.superscript == superscript
+ {
Some(footnotes)
} else {
self.labeling
.children
.iter()
- .find_map(|child| child.as_footnotes())
+ .flat_map(|child| child.as_footnotes())
+ .find(|child| child.superscript == superscript)
}
}
}
#[serde(rename = "@variable")]
variable: String,
+ #[serde(default, rename = "@superscript")]
+ superscript: bool,
+
#[serde(default, rename = "footnoteMapping")]
mappings: Vec<FootnoteMapping>,
}
--- /dev/null
+ Table 1
+╭────────────────────────┬─────────────────────────────────────────────────────────────────────────────╮
+│ │ GENDER │
+│ ├──────────────────────────┬──────────────────────────┬───────────────────────┤
+│ │ Male │ Female │ Total │
+│ ├───────┬──────────────────┼───────┬──────────────────┼────┬──────────────────┤
+│ │ Mean │Standard Deviation│ Mean │Standard Deviation│Mean│Standard Deviation│
+├────────────────────────┼───────┼──────────────────┼───────┼──────────────────┼────┼──────────────────┤
+│STATUS Examined AGE│ 52.3_a│ 9.2│ 51.8_a│ 10.7│52.0│ 10.1│
+│ Not Available AGE│ 50.8_a│ 7.4│ 49.4_a│ 8.2│50.6│ 7.4│
+│ Refused AGE│59.0[1]│. │50.0[1]│. │54.5│ 6.4│
+│ Total AGE│ 52.1│ 9.1│ 51.8│ 10.7│51.9│ 10.0│
+╰────────────────────────┴───────┴──────────────────┴───────┴──────────────────┴────┴──────────────────╯
+Note: Values in the same row and subtable not sharing the same subscript are significantly different at p< 0.05 in the two-sided test of equality for column means. Cells with no subscript are not included in the test. Tests assume equal variances.[2][3]
+1. This category is not used in comparisons because the sum of case weights is less than two.
+2. Tests are adjusted for all pairwise comparisons within a row of each innermost subtable using the Bonferroni correction.
+3. Pairwise comparisons are not performed for some subtables because of numerical problems.