Skip to content

[Repo Assist] Add Frame.interleave — side-by-side frame combining with tuple column keys#691

Merged
dsyme merged 2 commits intomasterfrom
repo-assist/implement-frame-interleave-187-af33e4c0968b8be7
Mar 22, 2026
Merged

[Repo Assist] Add Frame.interleave — side-by-side frame combining with tuple column keys#691
dsyme merged 2 commits intomasterfrom
repo-assist/implement-frame-interleave-187-af33e4c0968b8be7

Conversation

@github-actions
Copy link
Copy Markdown
Contributor

🤖 This PR was created by Repo Assist, an automated AI assistant.

Implements the long-requested Frame.interleave function from issue #187.

What it does

Given a list of frames with the same column keys, Frame.interleave places them side-by-side, tagging each frame's columns with its 1-based position in the input list. The result has a 'C * int column index.

let df1 = Frame.ofValues [("x","a",1); ("y","a",3); ("x","b",2); ("y","b",4)]
let df2 = Frame.ofValues [("x","a",5); ("y","a",7); ("x","b",6); ("y","b",8)]

Frame.interleave [df1; df2]
// Columns: [("a",1); ("b",1); ("a",2); ("b",2)]
//
//      ("a",1)  ("b",1)  ("a",2)  ("b",2)
// x ->    1        2        5        6
// y ->    3        4        7        8

Rows are aligned with an outer join, so frames with disjoint row keys also work.

Changes

  • src/Deedle/FrameModule.fs — adds Frame.interleave : Frame<'R,'C> list -> Frame<'R, 'C * int> after Frame.merge in the "Joining, merging and zipping" category
  • src/Deedle/FrameExtensions.fs — adds FrameUtils.Interleave(seq(Frame<'R,'C)>) C# extension method
  • tests/Deedle.Tests/Frame.fs — adds 6 tests:
    • Column key shape (tuple (colKey, 1-based-index))
    • Value correctness for a 2-frame case
    • 3-frame case (tags 1, 2, 3)
    • Single-frame identity (columns become ('c', 1))
    • Outer-join row alignment (missing values for non-shared rows)
    • Empty-list guard raises ArgumentException

Implementation notes

The implementation is minimal and composes existing primitives:

let interleave (frames: Frame<'R, 'C> list) : Frame<'R, 'C * int> =
    if List.isEmpty frames then
      invalidArg "frames" "The list of frames must be non-empty."
    frames
    |> List.mapi (fun i f -> f |> mapColKeys (fun c -> (c, i + 1)))
    |> List.reduce (fun acc f -> acc.Join(f))
```

This is essentially the workaround I described in my #187 comment, promoted to a named first-class function.

## Test Status

```
Passed!  - Failed: 0, Passed: 696, Skipped: 0, Total: 696

6 new tests added (690 base → 696). Full build (dotnet build src/Deedle/Deedle.fsproj -c Release) succeeds with 0 errors.

Closes #187

Generated by Repo Assist ·

To install this agentic workflow, run

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

… keys

Implements the long-requested Frame.interleave function (issue #187).
Given a list of frames, each frame's columns are tagged with their
1-based position in the input list, and all frames are joined (outer)
on the row index.

  Frame.interleave [df1; df2]
  // columns: [('a',1); ('b',1); ('a',2); ('b',2)]

Also exposes a C# extension method FrameUtils.Interleave on IEnumerable.
Adds 6 tests covering: column key shape, value correctness, 3-frame case,
single-frame identity, outer-join on rows, and empty-list guard.

Closes #187

Co-authored-by: Copilot <[email protected]>
@dsyme dsyme marked this pull request as ready for review March 22, 2026 21:45
@dsyme dsyme merged commit 794580a into master Mar 22, 2026
2 checks passed
@dsyme dsyme deleted the repo-assist/implement-frame-interleave-187-af33e4c0968b8be7 branch March 22, 2026 21:45
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.

More merging frames -

1 participant