Skip to main content

Module group

Module group 

Source
Expand description

Group-level iteration over a DataFrame key column.

Two rungs, cheapest first:

  1. Typed rows, grouped Rust-side — after Vec::<Row>::from_dataframe(&df)?, grouping is plain Rust. group_rows makes the idiom discoverable:

    let rows: Vec<Obs> = Vec::from_dataframe(&df)?;
    let by_site = group_rows(rows, |r| r.site.clone());
    // by_site: BTreeMap<String, Vec<Obs>> — plain Rust data, rayon-safe.
  2. Untyped, index-basedDataFrame::group_by computes group indices once (single pass, main thread) without extracting rows:

    let grouped = df.group_by("site")?;
    for (key, rows) in grouped.iter() { /* key: &GroupKey, rows: &[usize] */ }
    let mut out = NamedDataFrameListBuilder::with_capacity(grouped.len());
    for (key, sub) in grouped.frames() {
        // `sub` is a rooted `BuiltDataFrame`; deref to the view for push.
        out = out.push(key.label(), *sub);
    }

§Key semantics (vs R split())

  • Group order: factor keys follow level order (empty levels kept, like split()); character keys sort in byte order (R sorts in locale collation order — identical for ASCII); integer keys sort numerically; logical keys order FALSE, TRUE.
  • NA keys form one group, ordered last — a deliberate deviation from split(), which silently drops NA-keyed rows. A literal NA level (addNA(f)) also surfaces as GroupKey::Na.
  • Double key columns are an error: grouping on floating point is a footgun — cut() or factor() the column first.

§Composite keys (group_by_multi)

DataFrame::group_by_multi groups on several columns at once, keying by a GroupKey::Tuple of the per-column scalar keys. Non-NA groups match split(df, interaction(col1, col2, …, drop = TRUE)) (the first column varies fastest, R interaction()’s default) — exactly, for keys whose byte order coincides with the session’s collation (always true in the C locale; single-case ASCII in practice — the character-key byte-order choice above applies per column). Extending the single-column NA convention, any tuple with an NA in any component forms its own trailing group (first-encounter order) instead of being dropped as interaction() + split() would.

Structs§

GroupedDataFrame
A DataFrame partitioned by the values of one key column.

Enums§

GroupKey
The key of one group produced by DataFrame::group_by or DataFrame::group_by_multi.

Functions§

character_groups 🔒
Character keys: byte-order sort (BTreeMap), NA last.
column_keys 🔒
Per-row group key for one supported key column, in row order. NA cells — and factor NA codes / addNA() levels — become GroupKey::Na. Dispatches on SEXPTYPE exactly as DataFrame::group_by, surfacing the same unsupported-type error.
column_level_order 🔒
Distinct non-NA keys of one column in single-column group order (factor level order incl. empty levels; byte-sorted characters; numeric integers; FALSE then TRUE). NA is excluded — interaction() drops NA rows and NA-containing tuples are ordered separately. Reuses the single-column bucketers so the per-column order stays byte-identical to DataFrame::group_by. Only reached for supported columns (column_keys rejects the rest first).
factor_groups 🔒
Factor fast path: levels are the keys (level order, empty levels kept). NA codes — and a literal NA level from addNA() — land in GroupKey::Na.
group_rows
Group already-extracted rows by a key function.
group_rows_indices 🔒
Validate and convert one .rows list element — an integer / integerish vector of 1-based row indices — into a 0-based Vec<usize>. Rejects non-integer element types and any index outside 1..=nrow.
integer_groups 🔒
Integer keys: numeric sort (BTreeMap), NA (i32::MIN) last.
logical_groups 🔒
Logical keys: FALSE then TRUE (R’s sort order), NA last. Only keys present in the data appear.