Skip to main content

robust_rs/
datasets.rs

1//! Classic robust-statistics datasets, embedded for tests and examples.
2//!
3//! Values are sourced from R's `robustbase`; see `datasets/data/*.csv`.
4
5use ndarray::{Array1, Array2};
6
7/// Brownlee's stack-loss data: 21 observations, predictors (air flow, water
8/// temperature, acid concentration) and the response (stack loss). Returns
9/// `(X, y)` with `X` shaped `21 × 3`.
10pub fn stackloss() -> (Array2<f64>, Array1<f64>) {
11    parse_csv(include_str!("datasets/data/stackloss.csv"), 3)
12}
13
14/// Hertzsprung–Russell diagram of star cluster CYG OB1: 47 stars, predictor
15/// `log.Te`, response `log.light`. Cases 11, 20, 30, 34 are giant-star
16/// outliers. Returns `(X, y)` with `X` shaped `47 × 1`.
17pub fn stars_cyg() -> (Array2<f64>, Array1<f64>) {
18    parse_csv(include_str!("datasets/data/starsCYG.csv"), 1)
19}
20
21/// Parse an embedded, header-carrying CSV into a design matrix of the first
22/// `n_features` columns and a response vector from the final column. Panics on
23/// malformed data, which for a compiled-in dataset is a build-time bug.
24fn parse_csv(text: &str, n_features: usize) -> (Array2<f64>, Array1<f64>) {
25    let rows: Vec<Vec<f64>> = text
26        .lines()
27        .skip(1)
28        .map(str::trim)
29        .filter(|l| !l.is_empty())
30        .map(|l| {
31            l.split(',')
32                .map(|f| {
33                    f.trim()
34                        .parse::<f64>()
35                        .expect("dataset field is not numeric")
36                })
37                .collect()
38        })
39        .collect();
40
41    let n = rows.len();
42    let ncol = n_features + 1;
43    assert!(
44        rows.iter().all(|r| r.len() == ncol),
45        "dataset row width mismatch: expected {ncol} columns"
46    );
47
48    let mut x = Array2::zeros((n, n_features));
49    let mut y = Array1::zeros(n);
50    for (i, row) in rows.iter().enumerate() {
51        for j in 0..n_features {
52            x[[i, j]] = row[j];
53        }
54        y[i] = row[n_features];
55    }
56    (x, y)
57}