From 7de7359201ef0790f436fcbd226b1dbe4df58a87 Mon Sep 17 00:00:00 2001 From: Matt Van Horn <455140+mvanhorn@users.noreply.github.com> Date: Wed, 21 Oct 2026 07:39:30 -0700 Subject: [PATCH 1/4] Document all four pivot with overloads Fixes #1994 --- .../jetbrains/kotlinx/dataframe/api/with.kt | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/with.kt b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/with.kt index 190d0cfe7e..3025a73b14 100644 --- a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/with.kt +++ b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/with.kt @@ -4,6 +4,7 @@ import org.jetbrains.kotlinx.dataframe.AnyColumnReference import org.jetbrains.kotlinx.dataframe.DataFrame import org.jetbrains.kotlinx.dataframe.DataRow import org.jetbrains.kotlinx.dataframe.RowExpression +import org.jetbrains.kotlinx.dataframe.documentation.DocumentationUrls import org.jetbrains.kotlinx.dataframe.impl.aggregation.internal import org.jetbrains.kotlinx.dataframe.impl.aggregation.withExpr import org.jetbrains.kotlinx.dataframe.impl.emptyPath @@ -11,6 +12,16 @@ import kotlin.reflect.typeOf // region Pivot +/** + * Aggregates this [Pivot] by evaluating the given [row expression][expression] on every row of each pivot group. + * A single result is used directly; multiple results are collected for the corresponding pivot cell. + * + * For more information: {@include [DocumentationUrls.Pivot]} + * + * @param V The result type of [expression], captured at runtime for constructing the result columns. + * @param expression The expression evaluated for each row within each pivot group. + * @return A new [DataRow] with pivot keys as columns or column groups containing the computed results. + */ public inline fun Pivot.with(noinline expression: RowExpression): DataRow = delegate { with(expression) @@ -20,6 +31,16 @@ public inline fun Pivot.with(noinline expression: RowExpressio // region ReducedPivot +/** + * Transforms this [ReducedPivot] by evaluating the given [row expression][expression] on the single row + * selected by the reducer in each pivot group. + * + * For more information: {@include [DocumentationUrls.Pivot]} + * + * @param V The result type of [expression], captured at runtime for constructing the result columns. + * @param expression The expression evaluated on each selected row. + * @return A new [DataRow] with pivot keys as columns or column groups containing the computed results. + */ public inline fun ReducedPivot.with(noinline expression: RowExpression): DataRow = pivot.delegate { reduce(reducer).with(expression) @@ -29,6 +50,18 @@ public inline fun ReducedPivot.with(noinline expression: RowEx // region PivotGroupBy +/** + * Aggregates this [PivotGroupBy] by evaluating the given [row expression][expression] on every row + * in each group defined by the grouping and pivot keys. + * A single result is used directly; multiple results are collected for the corresponding pivot cell. + * + * For more information: {@include [DocumentationUrls.Pivot]} + * + * @param V The result type of [expression], captured at runtime for constructing the result columns. + * @param expression The expression evaluated for each row within each pivot cell group. + * @return A new [DataFrame] with the grouping key columns, one row per grouping key combination, + * and pivot keys as columns or column groups containing the computed results. + */ public inline fun PivotGroupBy.with(noinline expression: RowExpression): DataFrame { val type = typeOf() return aggregate { internal().withExpr(type, emptyPath(), expression) } @@ -38,6 +71,18 @@ public inline fun PivotGroupBy.with(noinline expression: RowEx // region ReducedPivotGroupBy +/** + * Transforms this [ReducedPivotGroupBy] by evaluating the given [row expression][expression] on the single row + * selected by the reducer in each group defined by the grouping and pivot keys. + * If [expression] returns a column reference, it is resolved to that column's value in the selected row. + * + * For more information: {@include [DocumentationUrls.Pivot]} + * + * @param V The result type of [expression], captured at runtime for constructing the result columns. + * @param expression The expression evaluated on each selected row. + * @return A new [DataFrame] with the grouping key columns, one row per grouping key combination, + * and pivot keys as columns or column groups containing the computed results. + */ public inline fun ReducedPivotGroupBy.with(noinline expression: RowExpression): DataFrame { val type = typeOf() return pivot.aggregate { From d87c1ab286dad2c5adf6c588110486701a8efb6d Mon Sep 17 00:00:00 2001 From: Matt Van Horn <455140+mvanhorn@users.noreply.github.com> Date: Thu, 22 Oct 2026 00:16:56 -0700 Subject: [PATCH 2/4] Share pivot with KDoc fragments and add samples Spell out the pivot cell result types for Pivot.with and PivotGroupBy.with (empty group yields null, one row yields V, several rows yield List) in one shared fragment, and document column-reference resolution once and include it in all four overloads. Add @sample examples from :samples to every overload, with new withOnPivotGroupBy and withOnReducedPivotGroupBy samples, and bracket the @param tags so KoDEx renders them. --- .../jetbrains/kotlinx/dataframe/api/with.kt | 68 ++++++++++++++++--- .../dataframe/samples/api/PivotSamples.kt | 16 +++++ 2 files changed, 73 insertions(+), 11 deletions(-) diff --git a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/with.kt b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/with.kt index 3025a73b14..c9d4f6c464 100644 --- a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/with.kt +++ b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/with.kt @@ -5,21 +5,48 @@ import org.jetbrains.kotlinx.dataframe.DataFrame import org.jetbrains.kotlinx.dataframe.DataRow import org.jetbrains.kotlinx.dataframe.RowExpression import org.jetbrains.kotlinx.dataframe.documentation.DocumentationUrls +import org.jetbrains.kotlinx.dataframe.documentation.ExcludeFromSources import org.jetbrains.kotlinx.dataframe.impl.aggregation.internal import org.jetbrains.kotlinx.dataframe.impl.aggregation.withExpr import org.jetbrains.kotlinx.dataframe.impl.emptyPath import kotlin.reflect.typeOf +// region docs + +/** + * For each pivot cell: an empty group yields `null` (type `V?`), a group of exactly one row yields + * that single value (type `V`), and a group of several rows yields a `List`. + */ +@ExcludeFromSources +private typealias PivotWithOneOrManyResultSnippet = Nothing + +/** + * If [expression\] returns a column reference, it is resolved to that column's value in the row + * the expression was evaluated on. + */ +@ExcludeFromSources +private typealias PivotWithColumnReferenceSnippet = Nothing + +// endregion + // region Pivot /** * Aggregates this [Pivot] by evaluating the given [row expression][expression] on every row of each pivot group. - * A single result is used directly; multiple results are collected for the corresponding pivot cell. + * + * @include [PivotWithOneOrManyResultSnippet] + * + * @include [PivotWithColumnReferenceSnippet] * * For more information: {@include [DocumentationUrls.Pivot]} * - * @param V The result type of [expression], captured at runtime for constructing the result columns. - * @param expression The expression evaluated for each row within each pivot group. + * ### Examples + * + * @sample [org.jetbrains.kotlinx.dataframe.samples.api.PivotSamples.withOnPivot_properties] + * @sample [org.jetbrains.kotlinx.dataframe.samples.api.PivotSamples.withOnPivot_strings] + * + * @param [V] The result type of [expression], captured at runtime for constructing the result columns. + * @param [expression] The expression evaluated for each row within each pivot group. * @return A new [DataRow] with pivot keys as columns or column groups containing the computed results. */ public inline fun Pivot.with(noinline expression: RowExpression): DataRow = @@ -35,10 +62,17 @@ public inline fun Pivot.with(noinline expression: RowExpressio * Transforms this [ReducedPivot] by evaluating the given [row expression][expression] on the single row * selected by the reducer in each pivot group. * + * @include [PivotWithColumnReferenceSnippet] + * * For more information: {@include [DocumentationUrls.Pivot]} * - * @param V The result type of [expression], captured at runtime for constructing the result columns. - * @param expression The expression evaluated on each selected row. + * ### Examples + * + * @sample [org.jetbrains.kotlinx.dataframe.samples.api.PivotSamples.pivotWith_properties] + * @sample [org.jetbrains.kotlinx.dataframe.samples.api.PivotSamples.pivotWith_strings] + * + * @param [V] The result type of [expression], captured at runtime for constructing the result columns. + * @param [expression] The expression evaluated on each selected row. * @return A new [DataRow] with pivot keys as columns or column groups containing the computed results. */ public inline fun ReducedPivot.with(noinline expression: RowExpression): DataRow = @@ -53,12 +87,19 @@ public inline fun ReducedPivot.with(noinline expression: RowEx /** * Aggregates this [PivotGroupBy] by evaluating the given [row expression][expression] on every row * in each group defined by the grouping and pivot keys. - * A single result is used directly; multiple results are collected for the corresponding pivot cell. + * + * @include [PivotWithOneOrManyResultSnippet] + * + * @include [PivotWithColumnReferenceSnippet] * * For more information: {@include [DocumentationUrls.Pivot]} * - * @param V The result type of [expression], captured at runtime for constructing the result columns. - * @param expression The expression evaluated for each row within each pivot cell group. + * ### Examples + * + * @sample [org.jetbrains.kotlinx.dataframe.samples.api.PivotSamples.withOnPivotGroupBy] + * + * @param [V] The result type of [expression], captured at runtime for constructing the result columns. + * @param [expression] The expression evaluated for each row within each pivot cell group. * @return A new [DataFrame] with the grouping key columns, one row per grouping key combination, * and pivot keys as columns or column groups containing the computed results. */ @@ -74,12 +115,17 @@ public inline fun PivotGroupBy.with(noinline expression: RowEx /** * Transforms this [ReducedPivotGroupBy] by evaluating the given [row expression][expression] on the single row * selected by the reducer in each group defined by the grouping and pivot keys. - * If [expression] returns a column reference, it is resolved to that column's value in the selected row. + * + * @include [PivotWithColumnReferenceSnippet] * * For more information: {@include [DocumentationUrls.Pivot]} * - * @param V The result type of [expression], captured at runtime for constructing the result columns. - * @param expression The expression evaluated on each selected row. + * ### Examples + * + * @sample [org.jetbrains.kotlinx.dataframe.samples.api.PivotSamples.withOnReducedPivotGroupBy] + * + * @param [V] The result type of [expression], captured at runtime for constructing the result columns. + * @param [expression] The expression evaluated on each selected row. * @return A new [DataFrame] with the grouping key columns, one row per grouping key combination, * and pivot keys as columns or column groups containing the computed results. */ diff --git a/samples/src/test/kotlin/org/jetbrains/kotlinx/dataframe/samples/api/PivotSamples.kt b/samples/src/test/kotlin/org/jetbrains/kotlinx/dataframe/samples/api/PivotSamples.kt index 0126d5687f..65a1defae3 100644 --- a/samples/src/test/kotlin/org/jetbrains/kotlinx/dataframe/samples/api/PivotSamples.kt +++ b/samples/src/test/kotlin/org/jetbrains/kotlinx/dataframe/samples/api/PivotSamples.kt @@ -514,6 +514,22 @@ class PivotSamples : DataFrameSampleHelper("pivot", "api") { // SampleEnd } + @Test + fun withOnPivotGroupBy() { + // SampleStart + df.groupBy { city }.pivot { isHappy }.with { name.lastName } + df.groupBy("city").pivot("isHappy").with { "name"["lastName"]() } + // SampleEnd + } + + @Test + fun withOnReducedPivotGroupBy() { + // SampleStart + df.groupBy { city }.pivot { isHappy }.maxBy { age }.with { name.lastName } + df.groupBy("city").pivot("isHappy").maxBy("age").with { "name"["lastName"]() } + // SampleEnd + } + // endregion // region aggregate From c3530800e395f9ba934280047615187b055b5f4f Mon Sep 17 00:00:00 2001 From: Matt Van Horn <455140+mvanhorn@users.noreply.github.com> Date: Thu, 22 Oct 2026 13:47:49 -0700 Subject: [PATCH 3/4] Link Pivot grammar in Pivot.with KDoc and say Aggregates for reduced overloads Pivot.with now points to the Pivot Grammar just before its examples, and the ReducedPivot.with and ReducedPivotGroupBy.with KDocs open with "Aggregates" instead of "Transforms", per review. --- .../main/kotlin/org/jetbrains/kotlinx/dataframe/api/with.kt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/with.kt b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/with.kt index c9d4f6c464..adb4afd4fc 100644 --- a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/with.kt +++ b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/with.kt @@ -40,6 +40,8 @@ private typealias PivotWithColumnReferenceSnippet = Nothing * * For more information: {@include [DocumentationUrls.Pivot]} * + * Check out the [`Pivot` Grammar][PivotDocs.Grammar]. + * * ### Examples * * @sample [org.jetbrains.kotlinx.dataframe.samples.api.PivotSamples.withOnPivot_properties] @@ -59,7 +61,7 @@ public inline fun Pivot.with(noinline expression: RowExpressio // region ReducedPivot /** - * Transforms this [ReducedPivot] by evaluating the given [row expression][expression] on the single row + * Aggregates this [ReducedPivot] by evaluating the given [row expression][expression] on the single row * selected by the reducer in each pivot group. * * @include [PivotWithColumnReferenceSnippet] @@ -113,7 +115,7 @@ public inline fun PivotGroupBy.with(noinline expression: RowEx // region ReducedPivotGroupBy /** - * Transforms this [ReducedPivotGroupBy] by evaluating the given [row expression][expression] on the single row + * Aggregates this [ReducedPivotGroupBy] by evaluating the given [row expression][expression] on the single row * selected by the reducer in each group defined by the grouping and pivot keys. * * @include [PivotWithColumnReferenceSnippet] From 6009beb3cd93cb4fa971c4541d20909674b58a65 Mon Sep 17 00:00:00 2001 From: Matt Van Horn <455140+mvanhorn@users.noreply.github.com> Date: Fri, 23 Oct 2026 21:20:35 -0700 Subject: [PATCH 4/4] Document the null result of reduced pivot with Add a shared KDoc fragment saying a pivot cell whose group has no row selected by the reducer yields null (type V?), otherwise the expression value (type V), and include it in ReducedPivot.with and ReducedPivotGroupBy.with, per review. --- .../org/jetbrains/kotlinx/dataframe/api/with.kt | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/with.kt b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/with.kt index adb4afd4fc..406947ab1c 100644 --- a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/with.kt +++ b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/with.kt @@ -20,6 +20,13 @@ import kotlin.reflect.typeOf @ExcludeFromSources private typealias PivotWithOneOrManyResultSnippet = Nothing +/** + * For each pivot cell: a group with no row selected by the reducer yields `null` (type `V?`), + * otherwise the value produced by the expression (type `V`). + */ +@ExcludeFromSources +private typealias PivotWithReducedResultSnippet = Nothing + /** * If [expression\] returns a column reference, it is resolved to that column's value in the row * the expression was evaluated on. @@ -64,6 +71,8 @@ public inline fun Pivot.with(noinline expression: RowExpressio * Aggregates this [ReducedPivot] by evaluating the given [row expression][expression] on the single row * selected by the reducer in each pivot group. * + * @include [PivotWithReducedResultSnippet] + * * @include [PivotWithColumnReferenceSnippet] * * For more information: {@include [DocumentationUrls.Pivot]} @@ -118,6 +127,8 @@ public inline fun PivotGroupBy.with(noinline expression: RowEx * Aggregates this [ReducedPivotGroupBy] by evaluating the given [row expression][expression] on the single row * selected by the reducer in each group defined by the grouping and pivot keys. * + * @include [PivotWithReducedResultSnippet] + * * @include [PivotWithColumnReferenceSnippet] * * For more information: {@include [DocumentationUrls.Pivot]}