Skip to content

[Repo Assist] Add Series.sweepLevel for hierarchical group normalisation — closes #236#638

Merged
dsyme merged 3 commits intomasterfrom
repo-assist/fix-issue-236-sweep-level-6a2dd75e36681e24
Mar 18, 2026
Merged

[Repo Assist] Add Series.sweepLevel for hierarchical group normalisation — closes #236#638
dsyme merged 3 commits intomasterfrom
repo-assist/fix-issue-236-sweep-level-6a2dd75e36681e24

Conversation

@github-actions
Copy link
Copy Markdown
Contributor

🤖 Repo Assist — automated implementation

Summary

Implements Series.sweepLevel as requested in #236. This function computes a group-level summary (via applyLevel) and then combines each element with its group's summary value using a binary operator — analogous to R's sweep().

New API

Series.sweepLevel
    (level   : 'K1 -> 'K2)
    (summaryOp : Series<'K1,'V> -> 'R)
    (sweepOp : 'V -> 'R -> 'S)
    (series  : Series<'K1,'V>)
    -> Series<'K1,'S>

Usage examples

let s = series [ (1,"a") => 10.0; (1,"b") => 40.0; (2,"a") => 3.0; (2,"b") => 7.0 ]

// Express each value as a fraction of its group sum
s |> Series.sweepLevel fst Stats.sum (/)
// (1,"a") => 0.2,  (1,"b") => 0.8,  (2,"a") => 0.3,  (2,"b") => 0.7

// Demean within each group
s |> Series.sweepLevel fst Stats.mean (-)

Implementation notes

  • Uses applyLevel for the group summary, then Series.map to look up each element's group summary by its projected key. This avoids the duplicate-key pitfall that arises when using getAll with repeated mapped keys.
  • The existing applyLevel / reduceLevel functions are unchanged — fully backwards-compatible.
  • Two files touched: SeriesModule.fs (implementation) and Tests/Series.fs (3 new tests).

Test Status

  • ✅ 3 new regression tests: normalise by group sum, demean by group mean, single-element groups
  • ✅ All 615 tests pass (was 612 before this change)
  • ✅ Build succeeded with 0 errors, 4 pre-existing warnings

Generated by Repo Assist ·

To install this agentic workflow, run

gh aw add githubnext/agentics/workflows/repo-assist.md@30f2254f2a7a944da1224df45d181a3f8faefd0d

Generated by Repo Assist ·

To install this agentic workflow, run

gh aw add githubnext/agentics/workflows/repo-assist.md@30f2254f2a7a944da1224df45d181a3f8faefd0d

Adds Series.sweepLevel, which applies a summary function to each group
(as defined by a level projection) and then combines each element with
its group summary using a binary sweep operator. This is analogous to
R's sweep() and enables common operations like within-group normalisation
and mean-centring in a single expression.

Example:
    s |> Series.sweepLevel fst Stats.sum (/)   // fraction of group sum
    s |> Series.sweepLevel fst Stats.mean (-)  // demean within group

Implementation uses applyLevel to build the summary and Series.map to
look up each element's group summary by its level key, avoiding issues
with duplicate key lookups. Three tests are added for the normalise,
demean, and single-element-group cases.

Co-authored-by: Copilot <[email protected]>
@dsyme dsyme marked this pull request as ready for review March 18, 2026 15:14
@dsyme dsyme merged commit 49faeee into master Mar 18, 2026
2 checks passed
@dsyme dsyme deleted the repo-assist/fix-issue-236-sweep-level-6a2dd75e36681e24 branch March 18, 2026 15:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant