From 6ca0db9b78f82563baafcf2da175364b6a163e2d Mon Sep 17 00:00:00 2001 From: Jolan Rensen Date: Tue, 18 Jul 2023 15:51:48 +0200 Subject: [PATCH 01/45] updating KDoc utils, similar to the continued-columnsselectiondsl branch --- .../dataframe/api/ColumnsSelectionDsl.kt | 68 ++++++++++++++----- .../jetbrains/kotlinx/dataframe/api/Nulls.kt | 60 ++++++++++++---- .../jetbrains/kotlinx/dataframe/api/update.kt | 32 ++++++--- .../kotlinx/dataframe/documentation/utils.kt | 12 +++- .../kotlinx/dataframe/documentation/utils.kt | 12 +++- 5 files changed, 142 insertions(+), 42 deletions(-) diff --git a/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/ColumnsSelectionDsl.kt b/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/ColumnsSelectionDsl.kt index 6fbcbe8c8d..40bbcb8bfc 100644 --- a/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/ColumnsSelectionDsl.kt +++ b/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/ColumnsSelectionDsl.kt @@ -3804,7 +3804,9 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum * #### Examples for this overload: * * `df.`[select][select]` { `[cols][cols]` { "a" in `[name][ColumnWithPath.name]` }.`[all][all]`() }` - * ## ‎ + * + *      + * * NOTE: This is an identity call and can be omitted in most cases. However, it can still prove useful * for readability or in combination with [recursively]. * @@ -4440,7 +4442,9 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum * `df.`[select][org.jetbrains.kotlinx.dataframe.DataFrame.select]` { `[colsOf][org.jetbrains.kotlinx.dataframe.api.colsOf]`<`[Int][Int]`>() }` * * `df.`[select][org.jetbrains.kotlinx.dataframe.DataFrame.select]` { `[colsOf][org.jetbrains.kotlinx.dataframe.api.colsOf]`<`[Int][Int]`> { it.`[size][org.jetbrains.kotlinx.dataframe.DataColumn.size]` > 10 } }` - * ## ‎ + * + *      + * * Alternatively, [colsOf][org.jetbrains.kotlinx.dataframe.api.colsOf] can also be called on existing columns: * * `df.`[select][org.jetbrains.kotlinx.dataframe.DataFrame.select]` { myColumnGroup.`[colsOf][org.jetbrains.kotlinx.dataframe.api.colsOf]`<`[Int][Int]`>() }` @@ -4448,7 +4452,9 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum * `df.`[select][org.jetbrains.kotlinx.dataframe.DataFrame.select]` { "myColumnGroup"().`[colsOf][org.jetbrains.kotlinx.dataframe.api.colsOf]`<`[Int][Int]`> { it.`[size][org.jetbrains.kotlinx.dataframe.DataColumn.size]` > 10 } }` * * `df.`[select][org.jetbrains.kotlinx.dataframe.DataFrame.select]` { (Type::myColumnGroup)().`[colsOf][org.jetbrains.kotlinx.dataframe.api.colsOf]`<`[Double][Double]`>() }` - * ## ‎ + * + *      + * * Finally, [colsOf][org.jetbrains.kotlinx.dataframe.api.colsOf] can also take a [KType] argument instead of a reified type. * This is useful when the type is not known at compile time or when the API function cannot be inlined. * @@ -4479,7 +4485,9 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum * `df.`[select][org.jetbrains.kotlinx.dataframe.DataFrame.select]` { `[colsOf][org.jetbrains.kotlinx.dataframe.api.colsOf]`<`[Int][Int]`>() }` * * `df.`[select][org.jetbrains.kotlinx.dataframe.DataFrame.select]` { `[colsOf][org.jetbrains.kotlinx.dataframe.api.colsOf]`<`[Int][Int]`> { it.`[size][org.jetbrains.kotlinx.dataframe.DataColumn.size]` > 10 } }` - * ## ‎ + * + *      + * * Alternatively, [colsOf][org.jetbrains.kotlinx.dataframe.api.colsOf] can also be called on existing columns: * * `df.`[select][org.jetbrains.kotlinx.dataframe.DataFrame.select]` { myColumnGroup.`[colsOf][org.jetbrains.kotlinx.dataframe.api.colsOf]`<`[Int][Int]`>() }` @@ -4487,7 +4495,9 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum * `df.`[select][org.jetbrains.kotlinx.dataframe.DataFrame.select]` { "myColumnGroup"().`[colsOf][org.jetbrains.kotlinx.dataframe.api.colsOf]`<`[Int][Int]`> { it.`[size][org.jetbrains.kotlinx.dataframe.DataColumn.size]` > 10 } }` * * `df.`[select][org.jetbrains.kotlinx.dataframe.DataFrame.select]` { (Type::myColumnGroup)().`[colsOf][org.jetbrains.kotlinx.dataframe.api.colsOf]`<`[Double][Double]`>() }` - * ## ‎ + * + *      + * * Finally, [colsOf][org.jetbrains.kotlinx.dataframe.api.colsOf] can also take a [KType] argument instead of a reified type. * This is useful when the type is not known at compile time or when the API function cannot be inlined. * @@ -4640,7 +4650,9 @@ public inline fun SingleColumn<*>.dfsOf(noinline filter: (ColumnWith * `df.`[select][DataFrame.select]` { `[colsOf][colsOf]`<`[Int][Int]`>() }` * * `df.`[select][DataFrame.select]` { `[colsOf][colsOf]`<`[Int][Int]`> { it.`[size][DataColumn.size]` > 10 } }` - * ## ‎ + * + *      + * * Alternatively, [colsOf] can also be called on existing columns: * * `df.`[select][DataFrame.select]` { myColumnGroup.`[colsOf][colsOf]`<`[Int][Int]`>() }` @@ -4648,7 +4660,9 @@ public inline fun SingleColumn<*>.dfsOf(noinline filter: (ColumnWith * `df.`[select][DataFrame.select]` { "myColumnGroup"().`[colsOf][colsOf]`<`[Int][Int]`> { it.`[size][DataColumn.size]` > 10 } }` * * `df.`[select][DataFrame.select]` { (Type::myColumnGroup)().`[colsOf][colsOf]`<`[Double][Double]`>() }` - * ## ‎ + * + *      + * * Finally, [colsOf] can also take a [KType] argument instead of a reified type. * This is useful when the type is not known at compile time or when the API function cannot be inlined. * @@ -4668,7 +4682,9 @@ internal interface ColsOf * `df.`[select][org.jetbrains.kotlinx.dataframe.DataFrame.select]` { `[colsOf][org.jetbrains.kotlinx.dataframe.api.colsOf]`<`[Int][Int]`>() }` * * `df.`[select][org.jetbrains.kotlinx.dataframe.DataFrame.select]` { `[colsOf][org.jetbrains.kotlinx.dataframe.api.colsOf]`<`[Int][Int]`> { it.`[size][org.jetbrains.kotlinx.dataframe.DataColumn.size]` > 10 } }` - * ## ‎ + * + *      + * * Alternatively, [colsOf][org.jetbrains.kotlinx.dataframe.api.colsOf] can also be called on existing columns: * * `df.`[select][org.jetbrains.kotlinx.dataframe.DataFrame.select]` { myColumnGroup.`[colsOf][org.jetbrains.kotlinx.dataframe.api.colsOf]`<`[Int][Int]`>() }` @@ -4676,7 +4692,9 @@ internal interface ColsOf * `df.`[select][org.jetbrains.kotlinx.dataframe.DataFrame.select]` { "myColumnGroup"().`[colsOf][org.jetbrains.kotlinx.dataframe.api.colsOf]`<`[Int][Int]`> { it.`[size][org.jetbrains.kotlinx.dataframe.DataColumn.size]` > 10 } }` * * `df.`[select][org.jetbrains.kotlinx.dataframe.DataFrame.select]` { (Type::myColumnGroup)().`[colsOf][org.jetbrains.kotlinx.dataframe.api.colsOf]`<`[Double][Double]`>() }` - * ## ‎ + * + *      + * * Finally, [colsOf][org.jetbrains.kotlinx.dataframe.api.colsOf] can also take a [KType] argument instead of a reified type. * This is useful when the type is not known at compile time or when the API function cannot be inlined. * @@ -4704,7 +4722,9 @@ private interface CommonColsOfDocs { * `df.`[select][org.jetbrains.kotlinx.dataframe.DataFrame.select]` { `[colsOf][org.jetbrains.kotlinx.dataframe.api.colsOf]`<`[Int][Int]`>() }` * * `df.`[select][org.jetbrains.kotlinx.dataframe.DataFrame.select]` { `[colsOf][org.jetbrains.kotlinx.dataframe.api.colsOf]`<`[Int][Int]`> { it.`[size][org.jetbrains.kotlinx.dataframe.DataColumn.size]` > 10 } }` - * ## ‎ + * + *      + * * Alternatively, [colsOf][org.jetbrains.kotlinx.dataframe.api.colsOf] can also be called on existing columns: * * `df.`[select][org.jetbrains.kotlinx.dataframe.DataFrame.select]` { myColumnGroup.`[colsOf][org.jetbrains.kotlinx.dataframe.api.colsOf]`<`[Int][Int]`>() }` @@ -4712,7 +4732,9 @@ private interface CommonColsOfDocs { * `df.`[select][org.jetbrains.kotlinx.dataframe.DataFrame.select]` { "myColumnGroup"().`[colsOf][org.jetbrains.kotlinx.dataframe.api.colsOf]`<`[Int][Int]`> { it.`[size][org.jetbrains.kotlinx.dataframe.DataColumn.size]` > 10 } }` * * `df.`[select][org.jetbrains.kotlinx.dataframe.DataFrame.select]` { (Type::myColumnGroup)().`[colsOf][org.jetbrains.kotlinx.dataframe.api.colsOf]`<`[Double][Double]`>() }` - * ## ‎ + * + *      + * * Finally, [colsOf][org.jetbrains.kotlinx.dataframe.api.colsOf] can also take a [KType] argument instead of a reified type. * This is useful when the type is not known at compile time or when the API function cannot be inlined. * @@ -4748,7 +4770,9 @@ public fun ColumnSet<*>.colsOf( * `df.`[select][org.jetbrains.kotlinx.dataframe.DataFrame.select]` { `[colsOf][org.jetbrains.kotlinx.dataframe.api.colsOf]`<`[Int][Int]`>() }` * * `df.`[select][org.jetbrains.kotlinx.dataframe.DataFrame.select]` { `[colsOf][org.jetbrains.kotlinx.dataframe.api.colsOf]`<`[Int][Int]`> { it.`[size][org.jetbrains.kotlinx.dataframe.DataColumn.size]` > 10 } }` - * ## ‎ + * + *      + * * Alternatively, [colsOf][org.jetbrains.kotlinx.dataframe.api.colsOf] can also be called on existing columns: * * `df.`[select][org.jetbrains.kotlinx.dataframe.DataFrame.select]` { myColumnGroup.`[colsOf][org.jetbrains.kotlinx.dataframe.api.colsOf]`<`[Int][Int]`>() }` @@ -4756,7 +4780,9 @@ public fun ColumnSet<*>.colsOf( * `df.`[select][org.jetbrains.kotlinx.dataframe.DataFrame.select]` { "myColumnGroup"().`[colsOf][org.jetbrains.kotlinx.dataframe.api.colsOf]`<`[Int][Int]`> { it.`[size][org.jetbrains.kotlinx.dataframe.DataColumn.size]` > 10 } }` * * `df.`[select][org.jetbrains.kotlinx.dataframe.DataFrame.select]` { (Type::myColumnGroup)().`[colsOf][org.jetbrains.kotlinx.dataframe.api.colsOf]`<`[Double][Double]`>() }` - * ## ‎ + * + *      + * * Finally, [colsOf][org.jetbrains.kotlinx.dataframe.api.colsOf] can also take a [KType] argument instead of a reified type. * This is useful when the type is not known at compile time or when the API function cannot be inlined. * @@ -4789,7 +4815,9 @@ public inline fun ColumnSet<*>.colsOf(noinline filter: (DataColumn() }` * * `df.`[select][org.jetbrains.kotlinx.dataframe.DataFrame.select]` { `[colsOf][org.jetbrains.kotlinx.dataframe.api.colsOf]`<`[Int][Int]`> { it.`[size][org.jetbrains.kotlinx.dataframe.DataColumn.size]` > 10 } }` - * ## ‎ + * + *      + * * Alternatively, [colsOf][org.jetbrains.kotlinx.dataframe.api.colsOf] can also be called on existing columns: * * `df.`[select][org.jetbrains.kotlinx.dataframe.DataFrame.select]` { myColumnGroup.`[colsOf][org.jetbrains.kotlinx.dataframe.api.colsOf]`<`[Int][Int]`>() }` @@ -4797,7 +4825,9 @@ public inline fun ColumnSet<*>.colsOf(noinline filter: (DataColumn().`[colsOf][org.jetbrains.kotlinx.dataframe.api.colsOf]`<`[Int][Int]`> { it.`[size][org.jetbrains.kotlinx.dataframe.DataColumn.size]` > 10 } }` * * `df.`[select][org.jetbrains.kotlinx.dataframe.DataFrame.select]` { (Type::myColumnGroup)().`[colsOf][org.jetbrains.kotlinx.dataframe.api.colsOf]`<`[Double][Double]`>() }` - * ## ‎ + * + *      + * * Finally, [colsOf][org.jetbrains.kotlinx.dataframe.api.colsOf] can also take a [KType] argument instead of a reified type. * This is useful when the type is not known at compile time or when the API function cannot be inlined. * @@ -4833,7 +4863,9 @@ public fun SingleColumn<*>.colsOf( * `df.`[select][org.jetbrains.kotlinx.dataframe.DataFrame.select]` { `[colsOf][org.jetbrains.kotlinx.dataframe.api.colsOf]`<`[Int][Int]`>() }` * * `df.`[select][org.jetbrains.kotlinx.dataframe.DataFrame.select]` { `[colsOf][org.jetbrains.kotlinx.dataframe.api.colsOf]`<`[Int][Int]`> { it.`[size][org.jetbrains.kotlinx.dataframe.DataColumn.size]` > 10 } }` - * ## ‎ + * + *      + * * Alternatively, [colsOf][org.jetbrains.kotlinx.dataframe.api.colsOf] can also be called on existing columns: * * `df.`[select][org.jetbrains.kotlinx.dataframe.DataFrame.select]` { myColumnGroup.`[colsOf][org.jetbrains.kotlinx.dataframe.api.colsOf]`<`[Int][Int]`>() }` @@ -4841,7 +4873,9 @@ public fun SingleColumn<*>.colsOf( * `df.`[select][org.jetbrains.kotlinx.dataframe.DataFrame.select]` { "myColumnGroup"().`[colsOf][org.jetbrains.kotlinx.dataframe.api.colsOf]`<`[Int][Int]`> { it.`[size][org.jetbrains.kotlinx.dataframe.DataColumn.size]` > 10 } }` * * `df.`[select][org.jetbrains.kotlinx.dataframe.DataFrame.select]` { (Type::myColumnGroup)().`[colsOf][org.jetbrains.kotlinx.dataframe.api.colsOf]`<`[Double][Double]`>() }` - * ## ‎ + * + *      + * * Finally, [colsOf][org.jetbrains.kotlinx.dataframe.api.colsOf] can also take a [KType] argument instead of a reified type. * This is useful when the type is not known at compile time or when the API function cannot be inlined. * diff --git a/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/Nulls.kt b/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/Nulls.kt index cc7bc35fc7..8828763626 100644 --- a/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/Nulls.kt +++ b/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/Nulls.kt @@ -53,7 +53,9 @@ private interface SetFillNullsOperationArg * Check out the [`fillNulls` Operation Usage][org.jetbrains.kotlinx.dataframe.api.FillNulls.Usage]. * * For more information: [See `fillNulls` on the documentation website.](https://kotlin.github.io/dataframe/fill.html#fillnulls) - * ## ‎ + * + *      + * * The columns to update need to be selected. See [Selecting Columns][org.jetbrains.kotlinx.dataframe.documentation.SelectingColumns] for all the selecting options. * * ## This Fill Nulls Overload @@ -70,7 +72,9 @@ private interface CommonFillNullsFunctionDoc * Check out the [`fillNulls` Operation Usage][org.jetbrains.kotlinx.dataframe.api.FillNulls.Usage]. * * For more information: [See `fillNulls` on the documentation website.](https://kotlin.github.io/dataframe/fill.html#fillnulls) - * ## ‎ + * + *      + * * The columns to update need to be selected. See [Selecting Columns][org.jetbrains.kotlinx.dataframe.documentation.SelectingColumns] for all the selecting options. * * ## This Fill Nulls Overload @@ -104,7 +108,9 @@ public fun DataFrame.fillNulls(columns: ColumnsSelector): Updat * Check out the [`fillNulls` Operation Usage][org.jetbrains.kotlinx.dataframe.api.FillNulls.Usage]. * * For more information: [See `fillNulls` on the documentation website.](https://kotlin.github.io/dataframe/fill.html#fillnulls) - * ## ‎ + * + *      + * * The columns to update need to be selected. See [Selecting Columns][org.jetbrains.kotlinx.dataframe.documentation.SelectingColumns] for all the selecting options. * * ## This Fill Nulls Overload @@ -130,7 +136,9 @@ public fun DataFrame.fillNulls(vararg columns: String): Update = * Check out the [`fillNulls` Operation Usage][org.jetbrains.kotlinx.dataframe.api.FillNulls.Usage]. * * For more information: [See `fillNulls` on the documentation website.](https://kotlin.github.io/dataframe/fill.html#fillnulls) - * ## ‎ + * + *      + * * The columns to update need to be selected. See [Selecting Columns][org.jetbrains.kotlinx.dataframe.documentation.SelectingColumns] for all the selecting options. * * ## This Fill Nulls Overload @@ -158,7 +166,9 @@ public fun DataFrame.fillNulls(vararg columns: KProperty): Update DataFrame.fillNaNs(columns: ColumnsSelector): Update< * Check out the [`fillNaNs` Operation Usage][org.jetbrains.kotlinx.dataframe.api.FillNaNs.Usage]. * * For more information: [See `fillNaNs` on the documentation website.](https://kotlin.github.io/dataframe/fill.html#fillnans) - * ## ‎ + * + *      + * * The columns to update need to be selected. See [Selecting Columns][org.jetbrains.kotlinx.dataframe.documentation.SelectingColumns] for all the selecting options. * ## This Fill NaNs Overload * Select columns using their [column names][String] @@ -327,7 +343,9 @@ public fun DataFrame.fillNaNs(vararg columns: String): Update = * Check out the [`fillNaNs` Operation Usage][org.jetbrains.kotlinx.dataframe.api.FillNaNs.Usage]. * * For more information: [See `fillNaNs` on the documentation website.](https://kotlin.github.io/dataframe/fill.html#fillnans) - * ## ‎ + * + *      + * * The columns to update need to be selected. See [Selecting Columns][org.jetbrains.kotlinx.dataframe.documentation.SelectingColumns] for all the selecting options. * ## This Fill NaNs Overload * Select columns using [KProperties][KProperty] ([KProperties API][org.jetbrains.kotlinx.dataframe.documentation.AccessApi.KPropertiesApi]). @@ -353,7 +371,9 @@ public fun DataFrame.fillNaNs(vararg columns: KProperty): Update DataFrame.fillNA(columns: ColumnsSelector): Update DataFrame.fillNA(vararg columns: String): Update = * Check out the [`fillNA` Operation Usage][org.jetbrains.kotlinx.dataframe.api.FillNA.Usage]. * * For more information: [See `fillNA` on the documentation website.](https://kotlin.github.io/dataframe/fill.html#fillna) - * ## ‎ + * + *      + * * The columns to update need to be selected. See [Selecting Columns][org.jetbrains.kotlinx.dataframe.documentation.SelectingColumns] for all the selecting options. * ## This Fill NA Overload * Select columns using [KProperties][KProperty] ([KProperties API][org.jetbrains.kotlinx.dataframe.documentation.AccessApi.KPropertiesApi]). @@ -526,7 +554,9 @@ public fun DataFrame.fillNA(vararg columns: KProperty): Update DataFrame.update(columns: ColumnsSelector): Update DataFrame.update(vararg columns: String): Update = up * Check out the [`update` Operation Usage][org.jetbrains.kotlinx.dataframe.api.Update.Usage]. * * For more information: [See `update` on the documentation website.](https://kotlin.github.io/dataframe/update.html) - * ## ‎ + * + *      + * * The columns to update need to be selected. See [Selecting Columns][org.jetbrains.kotlinx.dataframe.documentation.SelectingColumns] for all the selecting options. * ## This Update Overload * Select columns using [KProperties][KProperty] ([KProperties API][org.jetbrains.kotlinx.dataframe.documentation.AccessApi.KPropertiesApi]). @@ -194,7 +202,9 @@ public fun DataFrame.update(vararg columns: KProperty): Update Update.notNull(expression: UpdateExpression): * Check out the [`update` Operation Usage][org.jetbrains.kotlinx.dataframe.api.Update.Usage]. * * For more information: [See `update` on the documentation website.](https://kotlin.github.io/dataframe/update.html) - * ## ‎ + * + *      + * * The columns to update need to be selected. See [Selecting Columns][org.jetbrains.kotlinx.dataframe.documentation.SelectingColumns] for all the selecting options. * ## This Update Overload * ### This overload is a combination of [update] and [with][Update.with]. @@ -646,7 +658,9 @@ public fun DataFrame.update( * Check out the [`update` Operation Usage][org.jetbrains.kotlinx.dataframe.api.Update.Usage]. * * For more information: [See `update` on the documentation website.](https://kotlin.github.io/dataframe/update.html) - * ## ‎ + * + *      + * * The columns to update need to be selected. See [Selecting Columns][org.jetbrains.kotlinx.dataframe.documentation.SelectingColumns] for all the selecting options. * ## This Update Overload * ### This overload is a combination of [update] and [with][Update.with]. @@ -683,7 +697,9 @@ public fun DataFrame.update( * Check out the [`update` Operation Usage][org.jetbrains.kotlinx.dataframe.api.Update.Usage]. * * For more information: [See `update` on the documentation website.](https://kotlin.github.io/dataframe/update.html) - * ## ‎ + * + *      + * * The columns to update need to be selected. See [Selecting Columns][org.jetbrains.kotlinx.dataframe.documentation.SelectingColumns] for all the selecting options. * ## This Update Overload * ### This overload is a combination of [update] and [with][Update.with]. diff --git a/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/documentation/utils.kt b/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/documentation/utils.kt index 3660dd5397..8b49d557d7 100644 --- a/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/documentation/utils.kt +++ b/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/documentation/utils.kt @@ -1,4 +1,14 @@ package org.jetbrains.kotlinx.dataframe.documentation -/** ## ‎ */ +/** + * + *      + * + */ internal interface LineBreak + +/**      */ +internal interface Indent + +/**          */ +internal interface DoubleIndent diff --git a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/documentation/utils.kt b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/documentation/utils.kt index 3660dd5397..312bae0f4f 100644 --- a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/documentation/utils.kt +++ b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/documentation/utils.kt @@ -1,4 +1,14 @@ package org.jetbrains.kotlinx.dataframe.documentation -/** ## ‎ */ +/** + * + * {@include [Indent]} + * + */ internal interface LineBreak + +/**      */ +internal interface Indent + +/** {@include [Indent]}{@include [Indent]} */ +internal interface DoubleIndent From 172970a7b378c427303e58763fb892cdf85ef7b7 Mon Sep 17 00:00:00 2001 From: Jolan Rensen Date: Tue, 18 Jul 2023 15:52:11 +0200 Subject: [PATCH 02/45] added DataColumn.sortWith function with tests --- .../jetbrains/kotlinx/dataframe/api/sort.kt | 86 +++++++++++++++++++ .../jetbrains/kotlinx/dataframe/api/sort.kt | 71 +++++++++++++++ .../jetbrains/kotlinx/dataframe/api/sort.kt | 38 ++++++++ .../jetbrains/kotlinx/dataframe/api/sort.kt | 71 +++++++++++++++ 4 files changed, 266 insertions(+) create mode 100644 core/generated-sources/src/test/kotlin/org/jetbrains/kotlinx/dataframe/api/sort.kt create mode 100644 core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/api/sort.kt diff --git a/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/sort.kt b/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/sort.kt index 795006d42d..febb021862 100644 --- a/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/sort.kt +++ b/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/sort.kt @@ -5,8 +5,12 @@ import org.jetbrains.kotlinx.dataframe.DataFrame import org.jetbrains.kotlinx.dataframe.DataFrameExpression import org.jetbrains.kotlinx.dataframe.DataRow import org.jetbrains.kotlinx.dataframe.Selector +import org.jetbrains.kotlinx.dataframe.columns.ColumnGroup +import org.jetbrains.kotlinx.dataframe.documentation.Indent +import org.jetbrains.kotlinx.dataframe.documentation.LineBreak import org.jetbrains.kotlinx.dataframe.columns.ColumnReference import org.jetbrains.kotlinx.dataframe.columns.ColumnSet +import org.jetbrains.kotlinx.dataframe.columns.FrameColumn import org.jetbrains.kotlinx.dataframe.columns.UnresolvedColumnsPolicy import org.jetbrains.kotlinx.dataframe.columns.ValueColumn import org.jetbrains.kotlinx.dataframe.columns.toColumnSet @@ -56,6 +60,88 @@ public fun > DataColumn.sort(): ValueColumn = public fun > DataColumn.sortDesc(): ValueColumn = DataColumn.createValueColumn(name, values().sortedDescending(), type, defaultValue = defaultValue()) +/** + * ## Sort [DataColumn] With + * + * This function returns the sorted version of the current [ValueColumn], [FrameColumn], or [ColumnGroup] based + * on the given [Comparator]. The [comparator\] can either be given as an instance of [Comparator], or directly + * as a lambda. + * + * #### For example + * + * `df`[`[`][DataFrame.get]`"price"`[`]`][DataFrame.get]`.`[sortWith][sortWith]` { a, b -> a - b }` + * + * + *      + * + * `df.`[select][DataFrame.select]` {` + * + *     `name.`[sortWith][sortWith]`(myComparator) `[and][ColumnsSelectionDsl.and]` `[allAfter][ColumnsSelectionDsl.allAfter]`(name)` + * + * `}` + * + * @receiver The [DataColumn] to sort. This can be either a [ValueColumn], [FrameColumn], or [ColumnGroup] and will + * dictate the return type of the function. + * @param [comparator\] The [Comparator] to use for sorting the [DataColumn]. This can either be a [Comparator]<[T\]> or + * a lambda of type `(`[T][T\]`, `[T][T\]`) -> `[Int][Int]. + * @return The sorted [DataColumn] [this\] of the same type as the receiver. + */ +private interface CommonDataColumnSortWithDocs + +/** ## Sort [DataColumn][org.jetbrains.kotlinx.dataframe.DataColumn] With + * + * This function returns the sorted version of the current [ValueColumn][org.jetbrains.kotlinx.dataframe.columns.ValueColumn], [FrameColumn][org.jetbrains.kotlinx.dataframe.columns.FrameColumn], or [ColumnGroup][org.jetbrains.kotlinx.dataframe.columns.ColumnGroup] based + * on the given [Comparator]. The [comparator] can either be given as an instance of [Comparator], or directly + * as a lambda. + * + * #### For example + * + * `df`[`[`][org.jetbrains.kotlinx.dataframe.DataFrame.get]`"price"`[`]`][org.jetbrains.kotlinx.dataframe.DataFrame.get]`.`[sortWith][org.jetbrains.kotlinx.dataframe.api.sortWith]` { a, b -> a - b }` + * + * + *      + * + * `df.`[select][org.jetbrains.kotlinx.dataframe.DataFrame.select]` {` + * + *     `name.`[sortWith][org.jetbrains.kotlinx.dataframe.api.sortWith]`(myComparator) `[and][org.jetbrains.kotlinx.dataframe.api.ColumnsSelectionDsl.and]` `[allAfter][org.jetbrains.kotlinx.dataframe.api.ColumnsSelectionDsl.allAfter]`(name)` + * + * `}` + * + * @receiver The [DataColumn][org.jetbrains.kotlinx.dataframe.DataColumn] to sort. This can be either a [ValueColumn][org.jetbrains.kotlinx.dataframe.columns.ValueColumn], [FrameColumn][org.jetbrains.kotlinx.dataframe.columns.FrameColumn], or [ColumnGroup][org.jetbrains.kotlinx.dataframe.columns.ColumnGroup] and will + * dictate the return type of the function. + * @param [comparator] The [Comparator] to use for sorting the [DataColumn][org.jetbrains.kotlinx.dataframe.DataColumn]. This can either be a [Comparator]<[T]> or + * a lambda of type `(`[T][T]`, `[T][T]`) -> `[Int][Int]. + * @return The sorted [DataColumn][org.jetbrains.kotlinx.dataframe.DataColumn] [this] of the same type as the receiver. */ +public fun > C.sortWith(comparator: Comparator): C = + DataColumn.create(name, values().sortedWith(comparator), type) as C + +/** ## Sort [DataColumn][org.jetbrains.kotlinx.dataframe.DataColumn] With + * + * This function returns the sorted version of the current [ValueColumn][org.jetbrains.kotlinx.dataframe.columns.ValueColumn], [FrameColumn][org.jetbrains.kotlinx.dataframe.columns.FrameColumn], or [ColumnGroup][org.jetbrains.kotlinx.dataframe.columns.ColumnGroup] based + * on the given [Comparator]. The [comparator] can either be given as an instance of [Comparator], or directly + * as a lambda. + * + * #### For example + * + * `df`[`[`][org.jetbrains.kotlinx.dataframe.DataFrame.get]`"price"`[`]`][org.jetbrains.kotlinx.dataframe.DataFrame.get]`.`[sortWith][org.jetbrains.kotlinx.dataframe.api.sortWith]` { a, b -> a - b }` + * + * + *      + * + * `df.`[select][org.jetbrains.kotlinx.dataframe.DataFrame.select]` {` + * + *     `name.`[sortWith][org.jetbrains.kotlinx.dataframe.api.sortWith]`(myComparator) `[and][org.jetbrains.kotlinx.dataframe.api.ColumnsSelectionDsl.and]` `[allAfter][org.jetbrains.kotlinx.dataframe.api.ColumnsSelectionDsl.allAfter]`(name)` + * + * `}` + * + * @receiver The [DataColumn][org.jetbrains.kotlinx.dataframe.DataColumn] to sort. This can be either a [ValueColumn][org.jetbrains.kotlinx.dataframe.columns.ValueColumn], [FrameColumn][org.jetbrains.kotlinx.dataframe.columns.FrameColumn], or [ColumnGroup][org.jetbrains.kotlinx.dataframe.columns.ColumnGroup] and will + * dictate the return type of the function. + * @param [comparator] The [Comparator] to use for sorting the [DataColumn][org.jetbrains.kotlinx.dataframe.DataColumn]. This can either be a [Comparator]<[T]> or + * a lambda of type `(`[T][T]`, `[T][T]`) -> `[Int][Int]. + * @return The sorted [DataColumn][org.jetbrains.kotlinx.dataframe.DataColumn] [this] of the same type as the receiver. */ +public fun > C.sortWith(comparator: (T, T) -> Int): C = + sortWith(Comparator(comparator)) + // endregion // region DataFrame diff --git a/core/generated-sources/src/test/kotlin/org/jetbrains/kotlinx/dataframe/api/sort.kt b/core/generated-sources/src/test/kotlin/org/jetbrains/kotlinx/dataframe/api/sort.kt new file mode 100644 index 0000000000..f9cd0e914b --- /dev/null +++ b/core/generated-sources/src/test/kotlin/org/jetbrains/kotlinx/dataframe/api/sort.kt @@ -0,0 +1,71 @@ +package org.jetbrains.kotlinx.dataframe.api + +import io.kotest.matchers.shouldBe +import org.jetbrains.kotlinx.dataframe.DataColumn +import org.jetbrains.kotlinx.dataframe.alsoDebug +import org.jetbrains.kotlinx.dataframe.nrow +import org.junit.Test + +class SortDataColumn { + + @Test + fun `value column sort with`() { + val col = DataColumn.createValueColumn("", listOf(1, 6, 8, 4, 2, 9)) + val sortedCol = col.sort() + val descSortedCol = col.sortDesc() + + col.sortWith { a, b -> a - b } shouldBe sortedCol + col.sortWith { a, b -> b - a } shouldBe descSortedCol + + col.sortWith(Int::compareTo) shouldBe sortedCol + col.sortWith(Comparator(Int::compareTo)) shouldBe sortedCol + } + + @Test + fun `frame column sort with`() { + val col = DataColumn.createFrameColumn( + "", + listOf( + dataFrameOf("a")(1, 2), + dataFrameOf("a")(1), + dataFrameOf("a")(1, 2, 3) + ) + ) + val sortedCol = DataColumn.createFrameColumn( + "", + listOf( + dataFrameOf("a")(1), + dataFrameOf("a")(1, 2), + dataFrameOf("a")(1, 2, 3) + ) + ) + + col.sortWith { df1, df2 -> df1.nrow - df2.nrow } shouldBe sortedCol + col.sortWith(Comparator { df1, df2 -> df1.nrow - df2.nrow }) shouldBe sortedCol + } + + @Test + fun `column group sort with`() { + val a by column() + val b by column() + + val col = DataColumn.createColumnGroup( + "", + dataFrameOf( + columnOf(1, 3, 2) named a, + columnOf("hello", "world", "!") named b, + ), + ) + + val sortedCol = DataColumn.createColumnGroup( + "", + dataFrameOf( + columnOf(1, 2, 3) named a, + columnOf("hello", "!", "world") named b, + ), + ) + + col.sortWith { df1, df2 -> df1[a] - df2[a] } shouldBe sortedCol + col.sortWith(Comparator { df1, df2 -> df1[a] - df2[a] }) shouldBe sortedCol + } +} diff --git a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/sort.kt b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/sort.kt index 795006d42d..0bf6bcdcdb 100644 --- a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/sort.kt +++ b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/sort.kt @@ -5,8 +5,12 @@ import org.jetbrains.kotlinx.dataframe.DataFrame import org.jetbrains.kotlinx.dataframe.DataFrameExpression import org.jetbrains.kotlinx.dataframe.DataRow import org.jetbrains.kotlinx.dataframe.Selector +import org.jetbrains.kotlinx.dataframe.columns.ColumnGroup +import org.jetbrains.kotlinx.dataframe.documentation.Indent +import org.jetbrains.kotlinx.dataframe.documentation.LineBreak import org.jetbrains.kotlinx.dataframe.columns.ColumnReference import org.jetbrains.kotlinx.dataframe.columns.ColumnSet +import org.jetbrains.kotlinx.dataframe.columns.FrameColumn import org.jetbrains.kotlinx.dataframe.columns.UnresolvedColumnsPolicy import org.jetbrains.kotlinx.dataframe.columns.ValueColumn import org.jetbrains.kotlinx.dataframe.columns.toColumnSet @@ -56,6 +60,40 @@ public fun > DataColumn.sort(): ValueColumn = public fun > DataColumn.sortDesc(): ValueColumn = DataColumn.createValueColumn(name, values().sortedDescending(), type, defaultValue = defaultValue()) +/** + * ## Sort [DataColumn] With + * + * This function returns the sorted version of the current [ValueColumn], [FrameColumn], or [ColumnGroup] based + * on the given [Comparator]. The [comparator\] can either be given as an instance of [Comparator], or directly + * as a lambda. + * + * #### For example + * + * `df`[`[`][DataFrame.get]`"price"`[`]`][DataFrame.get]`.`[sortWith][sortWith]` { a, b -> a - b }` + * + * {@include [LineBreak]} + * `df.`[select][DataFrame.select]` {` + * + * {@include [Indent]}`name.`[sortWith][sortWith]`(myComparator) `[and][ColumnsSelectionDsl.and]` `[allAfter][ColumnsSelectionDsl.allAfter]`(name)` + * + * `}` + * + * @receiver The [DataColumn] to sort. This can be either a [ValueColumn], [FrameColumn], or [ColumnGroup] and will + * dictate the return type of the function. + * @param [comparator\] The [Comparator] to use for sorting the [DataColumn]. This can either be a [Comparator]<[T\]> or + * a lambda of type `(`[T][T\]`, `[T][T\]`) -> `[Int][Int]. + * @return The sorted [DataColumn] [this\] of the same type as the receiver. + */ +private interface CommonDataColumnSortWithDocs + +/** @include [CommonDataColumnSortWithDocs] */ +public fun > C.sortWith(comparator: Comparator): C = + DataColumn.create(name, values().sortedWith(comparator), type) as C + +/** @include [CommonDataColumnSortWithDocs] */ +public fun > C.sortWith(comparator: (T, T) -> Int): C = + sortWith(Comparator(comparator)) + // endregion // region DataFrame diff --git a/core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/api/sort.kt b/core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/api/sort.kt new file mode 100644 index 0000000000..f9cd0e914b --- /dev/null +++ b/core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/api/sort.kt @@ -0,0 +1,71 @@ +package org.jetbrains.kotlinx.dataframe.api + +import io.kotest.matchers.shouldBe +import org.jetbrains.kotlinx.dataframe.DataColumn +import org.jetbrains.kotlinx.dataframe.alsoDebug +import org.jetbrains.kotlinx.dataframe.nrow +import org.junit.Test + +class SortDataColumn { + + @Test + fun `value column sort with`() { + val col = DataColumn.createValueColumn("", listOf(1, 6, 8, 4, 2, 9)) + val sortedCol = col.sort() + val descSortedCol = col.sortDesc() + + col.sortWith { a, b -> a - b } shouldBe sortedCol + col.sortWith { a, b -> b - a } shouldBe descSortedCol + + col.sortWith(Int::compareTo) shouldBe sortedCol + col.sortWith(Comparator(Int::compareTo)) shouldBe sortedCol + } + + @Test + fun `frame column sort with`() { + val col = DataColumn.createFrameColumn( + "", + listOf( + dataFrameOf("a")(1, 2), + dataFrameOf("a")(1), + dataFrameOf("a")(1, 2, 3) + ) + ) + val sortedCol = DataColumn.createFrameColumn( + "", + listOf( + dataFrameOf("a")(1), + dataFrameOf("a")(1, 2), + dataFrameOf("a")(1, 2, 3) + ) + ) + + col.sortWith { df1, df2 -> df1.nrow - df2.nrow } shouldBe sortedCol + col.sortWith(Comparator { df1, df2 -> df1.nrow - df2.nrow }) shouldBe sortedCol + } + + @Test + fun `column group sort with`() { + val a by column() + val b by column() + + val col = DataColumn.createColumnGroup( + "", + dataFrameOf( + columnOf(1, 3, 2) named a, + columnOf("hello", "world", "!") named b, + ), + ) + + val sortedCol = DataColumn.createColumnGroup( + "", + dataFrameOf( + columnOf(1, 2, 3) named a, + columnOf("hello", "!", "world") named b, + ), + ) + + col.sortWith { df1, df2 -> df1[a] - df2[a] } shouldBe sortedCol + col.sortWith(Comparator { df1, df2 -> df1[a] - df2[a] }) shouldBe sortedCol + } +} From 7149616161eda805d16e8dde4b08284531d6ec63 Mon Sep 17 00:00:00 2001 From: Jolan Rensen Date: Tue, 18 Jul 2023 16:26:22 +0200 Subject: [PATCH 03/45] Linting --- .../jetbrains/kotlinx/dataframe/api/sort.kt | 264 ------------------ .../jetbrains/kotlinx/dataframe/api/sort.kt | 71 ----- .../jetbrains/kotlinx/dataframe/api/sort.kt | 4 +- .../jetbrains/kotlinx/dataframe/api/sort.kt | 1 - 4 files changed, 2 insertions(+), 338 deletions(-) delete mode 100644 core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/sort.kt delete mode 100644 core/generated-sources/src/test/kotlin/org/jetbrains/kotlinx/dataframe/api/sort.kt diff --git a/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/sort.kt b/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/sort.kt deleted file mode 100644 index febb021862..0000000000 --- a/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/sort.kt +++ /dev/null @@ -1,264 +0,0 @@ -package org.jetbrains.kotlinx.dataframe.api - -import org.jetbrains.kotlinx.dataframe.DataColumn -import org.jetbrains.kotlinx.dataframe.DataFrame -import org.jetbrains.kotlinx.dataframe.DataFrameExpression -import org.jetbrains.kotlinx.dataframe.DataRow -import org.jetbrains.kotlinx.dataframe.Selector -import org.jetbrains.kotlinx.dataframe.columns.ColumnGroup -import org.jetbrains.kotlinx.dataframe.documentation.Indent -import org.jetbrains.kotlinx.dataframe.documentation.LineBreak -import org.jetbrains.kotlinx.dataframe.columns.ColumnReference -import org.jetbrains.kotlinx.dataframe.columns.ColumnSet -import org.jetbrains.kotlinx.dataframe.columns.FrameColumn -import org.jetbrains.kotlinx.dataframe.columns.UnresolvedColumnsPolicy -import org.jetbrains.kotlinx.dataframe.columns.ValueColumn -import org.jetbrains.kotlinx.dataframe.columns.toColumnSet -import org.jetbrains.kotlinx.dataframe.impl.api.SortFlag -import org.jetbrains.kotlinx.dataframe.impl.api.addFlag -import org.jetbrains.kotlinx.dataframe.impl.api.sortByImpl -import org.jetbrains.kotlinx.dataframe.impl.columns.newColumnWithActualType -import org.jetbrains.kotlinx.dataframe.impl.columns.toColumnSet -import org.jetbrains.kotlinx.dataframe.index -import org.jetbrains.kotlinx.dataframe.nrow -import org.jetbrains.kotlinx.dataframe.type -import org.jetbrains.kotlinx.dataframe.util.ITERABLE_COLUMNS_DEPRECATION_MESSAGE -import kotlin.reflect.KProperty - -public interface SortDsl : ColumnsSelectionDsl { - public fun ColumnSet.desc(): ColumnSet = addFlag(SortFlag.Reversed) - - public fun String.desc(): ColumnSet?> = invoke>().desc() - - public fun KProperty.desc(): ColumnSet = toColumnAccessor().desc() - - public fun ColumnSet.nullsLast(flag: Boolean = true): ColumnSet = - if (flag) addFlag(SortFlag.NullsLast) else this - - public fun String.nullsLast(flag: Boolean = true): ColumnSet?> = - invoke>().nullsLast(flag) - - public fun KProperty.nullsLast(flag: Boolean = true): ColumnSet = toColumnAccessor().nullsLast(flag) -} - -/** - * [SortColumnsSelector] is used to express or select multiple columns to sort by, represented by [ColumnSet]``, - * using the context of [SortDsl]`` as `this` and `it`. - * - * So: - * ```kotlin - * SortDsl.(it: SortDsl) -> ColumnSet - * ``` - */ -public typealias SortColumnsSelector = Selector, ColumnSet> - -// region DataColumn - -public fun > DataColumn.sort(): ValueColumn = - DataColumn.createValueColumn(name, values().sorted(), type, defaultValue = defaultValue()) - -public fun > DataColumn.sortDesc(): ValueColumn = - DataColumn.createValueColumn(name, values().sortedDescending(), type, defaultValue = defaultValue()) - -/** - * ## Sort [DataColumn] With - * - * This function returns the sorted version of the current [ValueColumn], [FrameColumn], or [ColumnGroup] based - * on the given [Comparator]. The [comparator\] can either be given as an instance of [Comparator], or directly - * as a lambda. - * - * #### For example - * - * `df`[`[`][DataFrame.get]`"price"`[`]`][DataFrame.get]`.`[sortWith][sortWith]` { a, b -> a - b }` - * - * - *      - * - * `df.`[select][DataFrame.select]` {` - * - *     `name.`[sortWith][sortWith]`(myComparator) `[and][ColumnsSelectionDsl.and]` `[allAfter][ColumnsSelectionDsl.allAfter]`(name)` - * - * `}` - * - * @receiver The [DataColumn] to sort. This can be either a [ValueColumn], [FrameColumn], or [ColumnGroup] and will - * dictate the return type of the function. - * @param [comparator\] The [Comparator] to use for sorting the [DataColumn]. This can either be a [Comparator]<[T\]> or - * a lambda of type `(`[T][T\]`, `[T][T\]`) -> `[Int][Int]. - * @return The sorted [DataColumn] [this\] of the same type as the receiver. - */ -private interface CommonDataColumnSortWithDocs - -/** ## Sort [DataColumn][org.jetbrains.kotlinx.dataframe.DataColumn] With - * - * This function returns the sorted version of the current [ValueColumn][org.jetbrains.kotlinx.dataframe.columns.ValueColumn], [FrameColumn][org.jetbrains.kotlinx.dataframe.columns.FrameColumn], or [ColumnGroup][org.jetbrains.kotlinx.dataframe.columns.ColumnGroup] based - * on the given [Comparator]. The [comparator] can either be given as an instance of [Comparator], or directly - * as a lambda. - * - * #### For example - * - * `df`[`[`][org.jetbrains.kotlinx.dataframe.DataFrame.get]`"price"`[`]`][org.jetbrains.kotlinx.dataframe.DataFrame.get]`.`[sortWith][org.jetbrains.kotlinx.dataframe.api.sortWith]` { a, b -> a - b }` - * - * - *      - * - * `df.`[select][org.jetbrains.kotlinx.dataframe.DataFrame.select]` {` - * - *     `name.`[sortWith][org.jetbrains.kotlinx.dataframe.api.sortWith]`(myComparator) `[and][org.jetbrains.kotlinx.dataframe.api.ColumnsSelectionDsl.and]` `[allAfter][org.jetbrains.kotlinx.dataframe.api.ColumnsSelectionDsl.allAfter]`(name)` - * - * `}` - * - * @receiver The [DataColumn][org.jetbrains.kotlinx.dataframe.DataColumn] to sort. This can be either a [ValueColumn][org.jetbrains.kotlinx.dataframe.columns.ValueColumn], [FrameColumn][org.jetbrains.kotlinx.dataframe.columns.FrameColumn], or [ColumnGroup][org.jetbrains.kotlinx.dataframe.columns.ColumnGroup] and will - * dictate the return type of the function. - * @param [comparator] The [Comparator] to use for sorting the [DataColumn][org.jetbrains.kotlinx.dataframe.DataColumn]. This can either be a [Comparator]<[T]> or - * a lambda of type `(`[T][T]`, `[T][T]`) -> `[Int][Int]. - * @return The sorted [DataColumn][org.jetbrains.kotlinx.dataframe.DataColumn] [this] of the same type as the receiver. */ -public fun > C.sortWith(comparator: Comparator): C = - DataColumn.create(name, values().sortedWith(comparator), type) as C - -/** ## Sort [DataColumn][org.jetbrains.kotlinx.dataframe.DataColumn] With - * - * This function returns the sorted version of the current [ValueColumn][org.jetbrains.kotlinx.dataframe.columns.ValueColumn], [FrameColumn][org.jetbrains.kotlinx.dataframe.columns.FrameColumn], or [ColumnGroup][org.jetbrains.kotlinx.dataframe.columns.ColumnGroup] based - * on the given [Comparator]. The [comparator] can either be given as an instance of [Comparator], or directly - * as a lambda. - * - * #### For example - * - * `df`[`[`][org.jetbrains.kotlinx.dataframe.DataFrame.get]`"price"`[`]`][org.jetbrains.kotlinx.dataframe.DataFrame.get]`.`[sortWith][org.jetbrains.kotlinx.dataframe.api.sortWith]` { a, b -> a - b }` - * - * - *      - * - * `df.`[select][org.jetbrains.kotlinx.dataframe.DataFrame.select]` {` - * - *     `name.`[sortWith][org.jetbrains.kotlinx.dataframe.api.sortWith]`(myComparator) `[and][org.jetbrains.kotlinx.dataframe.api.ColumnsSelectionDsl.and]` `[allAfter][org.jetbrains.kotlinx.dataframe.api.ColumnsSelectionDsl.allAfter]`(name)` - * - * `}` - * - * @receiver The [DataColumn][org.jetbrains.kotlinx.dataframe.DataColumn] to sort. This can be either a [ValueColumn][org.jetbrains.kotlinx.dataframe.columns.ValueColumn], [FrameColumn][org.jetbrains.kotlinx.dataframe.columns.FrameColumn], or [ColumnGroup][org.jetbrains.kotlinx.dataframe.columns.ColumnGroup] and will - * dictate the return type of the function. - * @param [comparator] The [Comparator] to use for sorting the [DataColumn][org.jetbrains.kotlinx.dataframe.DataColumn]. This can either be a [Comparator]<[T]> or - * a lambda of type `(`[T][T]`, `[T][T]`) -> `[Int][Int]. - * @return The sorted [DataColumn][org.jetbrains.kotlinx.dataframe.DataColumn] [this] of the same type as the receiver. */ -public fun > C.sortWith(comparator: (T, T) -> Int): C = - sortWith(Comparator(comparator)) - -// endregion - -// region DataFrame - -public fun DataFrame.sortBy(columns: SortColumnsSelector): DataFrame = sortByImpl( - UnresolvedColumnsPolicy.Fail, columns -) - -@Deprecated( - message = ITERABLE_COLUMNS_DEPRECATION_MESSAGE, - replaceWith = ReplaceWith( - "sortBy { cols.toColumnSet() }", - "org.jetbrains.kotlinx.dataframe.impl.columns.toColumnSet" - ), - level = DeprecationLevel.ERROR -) -public fun DataFrame.sortBy(cols: Iterable?>>): DataFrame = - sortBy { cols.toColumnSet() } - -public fun DataFrame.sortBy(vararg cols: ColumnReference?>): DataFrame = - sortBy { cols.toColumnSet() } - -public fun DataFrame.sortBy(vararg cols: String): DataFrame = sortBy { cols.toColumnSet() } - -public fun DataFrame.sortBy(vararg cols: KProperty?>): DataFrame = sortBy { cols.toColumnSet() } - -public fun DataFrame.sortWith(comparator: Comparator>): DataFrame { - val permutation = rows().sortedWith(comparator).map { it.index } - return this[permutation] -} - -public fun DataFrame.sortWith(comparator: (DataRow, DataRow) -> Int): DataFrame = - sortWith(Comparator(comparator)) - -public fun DataFrame.sortByDesc(columns: SortColumnsSelector): DataFrame { - val set = columns.toColumnSet() - return sortByImpl { set.desc() } -} - -public fun DataFrame.sortByDesc(vararg columns: KProperty?>): DataFrame = - sortByDesc { columns.toColumnSet() } - -public fun DataFrame.sortByDesc(vararg columns: String): DataFrame = sortByDesc { columns.toColumnSet() } - -public fun DataFrame.sortByDesc(vararg columns: ColumnReference?>): DataFrame = - sortByDesc { columns.toColumnSet() } - -@Deprecated( - message = ITERABLE_COLUMNS_DEPRECATION_MESSAGE, - replaceWith = ReplaceWith( - "sortByDesc { columns.toColumnSet() }", - "org.jetbrains.kotlinx.dataframe.columns.toColumnSet", - ), - level = DeprecationLevel.ERROR, -) -public fun DataFrame.sortByDesc(columns: Iterable?>>): DataFrame = - sortByDesc { columns.toColumnSet() } - -// endregion - -// region GroupBy - -public fun GroupBy.sortBy(vararg cols: String): GroupBy = sortBy { cols.toColumnSet() } - -public fun GroupBy.sortBy(vararg cols: ColumnReference?>): GroupBy = - sortBy { cols.toColumnSet() } - -public fun GroupBy.sortBy(vararg cols: KProperty?>): GroupBy = - sortBy { cols.toColumnSet() } - -public fun GroupBy.sortBy(selector: SortColumnsSelector): GroupBy = sortByImpl(selector) - -public fun GroupBy.sortByDesc(vararg cols: String): GroupBy = sortByDesc { cols.toColumnSet() } - -public fun GroupBy.sortByDesc(vararg cols: ColumnReference?>): GroupBy = - sortByDesc { cols.toColumnSet() } - -public fun GroupBy.sortByDesc(vararg cols: KProperty?>): GroupBy = - sortByDesc { cols.toColumnSet() } - -public fun GroupBy.sortByDesc(selector: SortColumnsSelector): GroupBy { - val set = selector.toColumnSet() - return sortByImpl { set.desc() } -} - -private fun GroupBy.createColumnFromGroupExpression( - receiver: ColumnsSelectionDsl, - expression: DataFrameExpression, -): DataColumn { - return receiver.newColumnWithActualType("") { row -> - val group = row[groups] - expression(group, group) - } -} - -public fun GroupBy.sortByGroup( - nullsLast: Boolean = false, - expression: DataFrameExpression, -): GroupBy = toDataFrame().sortBy { - createColumnFromGroupExpression(this, expression).nullsLast(nullsLast) -}.asGroupBy(groups) - -public fun GroupBy.sortByGroupDesc( - nullsLast: Boolean = false, - expression: DataFrameExpression, -): GroupBy = toDataFrame().sortBy { - createColumnFromGroupExpression(this, expression).desc().nullsLast(nullsLast) -}.asGroupBy(groups) - -public fun GroupBy.sortByCountAsc(): GroupBy = sortByGroup { nrow } - -public fun GroupBy.sortByCount(): GroupBy = sortByGroupDesc { nrow } - -public fun GroupBy.sortByKeyDesc(nullsLast: Boolean = false): GroupBy = toDataFrame() - .sortBy { keys.columns().toColumnSet().desc().nullsLast(nullsLast) }.asGroupBy(groups) - -public fun GroupBy.sortByKey(nullsLast: Boolean = false): GroupBy = toDataFrame() - .sortBy { keys.columns().toColumnSet().nullsLast(nullsLast) }.asGroupBy(groups) - -// endregion diff --git a/core/generated-sources/src/test/kotlin/org/jetbrains/kotlinx/dataframe/api/sort.kt b/core/generated-sources/src/test/kotlin/org/jetbrains/kotlinx/dataframe/api/sort.kt deleted file mode 100644 index f9cd0e914b..0000000000 --- a/core/generated-sources/src/test/kotlin/org/jetbrains/kotlinx/dataframe/api/sort.kt +++ /dev/null @@ -1,71 +0,0 @@ -package org.jetbrains.kotlinx.dataframe.api - -import io.kotest.matchers.shouldBe -import org.jetbrains.kotlinx.dataframe.DataColumn -import org.jetbrains.kotlinx.dataframe.alsoDebug -import org.jetbrains.kotlinx.dataframe.nrow -import org.junit.Test - -class SortDataColumn { - - @Test - fun `value column sort with`() { - val col = DataColumn.createValueColumn("", listOf(1, 6, 8, 4, 2, 9)) - val sortedCol = col.sort() - val descSortedCol = col.sortDesc() - - col.sortWith { a, b -> a - b } shouldBe sortedCol - col.sortWith { a, b -> b - a } shouldBe descSortedCol - - col.sortWith(Int::compareTo) shouldBe sortedCol - col.sortWith(Comparator(Int::compareTo)) shouldBe sortedCol - } - - @Test - fun `frame column sort with`() { - val col = DataColumn.createFrameColumn( - "", - listOf( - dataFrameOf("a")(1, 2), - dataFrameOf("a")(1), - dataFrameOf("a")(1, 2, 3) - ) - ) - val sortedCol = DataColumn.createFrameColumn( - "", - listOf( - dataFrameOf("a")(1), - dataFrameOf("a")(1, 2), - dataFrameOf("a")(1, 2, 3) - ) - ) - - col.sortWith { df1, df2 -> df1.nrow - df2.nrow } shouldBe sortedCol - col.sortWith(Comparator { df1, df2 -> df1.nrow - df2.nrow }) shouldBe sortedCol - } - - @Test - fun `column group sort with`() { - val a by column() - val b by column() - - val col = DataColumn.createColumnGroup( - "", - dataFrameOf( - columnOf(1, 3, 2) named a, - columnOf("hello", "world", "!") named b, - ), - ) - - val sortedCol = DataColumn.createColumnGroup( - "", - dataFrameOf( - columnOf(1, 2, 3) named a, - columnOf("hello", "!", "world") named b, - ), - ) - - col.sortWith { df1, df2 -> df1[a] - df2[a] } shouldBe sortedCol - col.sortWith(Comparator { df1, df2 -> df1[a] - df2[a] }) shouldBe sortedCol - } -} diff --git a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/sort.kt b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/sort.kt index 0bf6bcdcdb..fc949c1e6d 100644 --- a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/sort.kt +++ b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/sort.kt @@ -6,14 +6,14 @@ import org.jetbrains.kotlinx.dataframe.DataFrameExpression import org.jetbrains.kotlinx.dataframe.DataRow import org.jetbrains.kotlinx.dataframe.Selector import org.jetbrains.kotlinx.dataframe.columns.ColumnGroup -import org.jetbrains.kotlinx.dataframe.documentation.Indent -import org.jetbrains.kotlinx.dataframe.documentation.LineBreak import org.jetbrains.kotlinx.dataframe.columns.ColumnReference import org.jetbrains.kotlinx.dataframe.columns.ColumnSet import org.jetbrains.kotlinx.dataframe.columns.FrameColumn import org.jetbrains.kotlinx.dataframe.columns.UnresolvedColumnsPolicy import org.jetbrains.kotlinx.dataframe.columns.ValueColumn import org.jetbrains.kotlinx.dataframe.columns.toColumnSet +import org.jetbrains.kotlinx.dataframe.documentation.Indent +import org.jetbrains.kotlinx.dataframe.documentation.LineBreak import org.jetbrains.kotlinx.dataframe.impl.api.SortFlag import org.jetbrains.kotlinx.dataframe.impl.api.addFlag import org.jetbrains.kotlinx.dataframe.impl.api.sortByImpl diff --git a/core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/api/sort.kt b/core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/api/sort.kt index f9cd0e914b..a04dc3f8fd 100644 --- a/core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/api/sort.kt +++ b/core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/api/sort.kt @@ -2,7 +2,6 @@ package org.jetbrains.kotlinx.dataframe.api import io.kotest.matchers.shouldBe import org.jetbrains.kotlinx.dataframe.DataColumn -import org.jetbrains.kotlinx.dataframe.alsoDebug import org.jetbrains.kotlinx.dataframe.nrow import org.junit.Test From 7c13916078a106e40ec7f88a40dace6077ee0dfc Mon Sep 17 00:00:00 2001 From: Jolan Rensen Date: Tue, 18 Jul 2023 16:27:52 +0200 Subject: [PATCH 04/45] Linting --- .../jetbrains/kotlinx/dataframe/api/sort.kt | 264 ++++++++++++++++++ .../jetbrains/kotlinx/dataframe/api/sort.kt | 70 +++++ 2 files changed, 334 insertions(+) create mode 100644 core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/sort.kt create mode 100644 core/generated-sources/src/test/kotlin/org/jetbrains/kotlinx/dataframe/api/sort.kt diff --git a/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/sort.kt b/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/sort.kt new file mode 100644 index 0000000000..895c14f619 --- /dev/null +++ b/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/sort.kt @@ -0,0 +1,264 @@ +package org.jetbrains.kotlinx.dataframe.api + +import org.jetbrains.kotlinx.dataframe.DataColumn +import org.jetbrains.kotlinx.dataframe.DataFrame +import org.jetbrains.kotlinx.dataframe.DataFrameExpression +import org.jetbrains.kotlinx.dataframe.DataRow +import org.jetbrains.kotlinx.dataframe.Selector +import org.jetbrains.kotlinx.dataframe.columns.ColumnGroup +import org.jetbrains.kotlinx.dataframe.columns.ColumnReference +import org.jetbrains.kotlinx.dataframe.columns.ColumnSet +import org.jetbrains.kotlinx.dataframe.columns.FrameColumn +import org.jetbrains.kotlinx.dataframe.columns.UnresolvedColumnsPolicy +import org.jetbrains.kotlinx.dataframe.columns.ValueColumn +import org.jetbrains.kotlinx.dataframe.columns.toColumnSet +import org.jetbrains.kotlinx.dataframe.documentation.Indent +import org.jetbrains.kotlinx.dataframe.documentation.LineBreak +import org.jetbrains.kotlinx.dataframe.impl.api.SortFlag +import org.jetbrains.kotlinx.dataframe.impl.api.addFlag +import org.jetbrains.kotlinx.dataframe.impl.api.sortByImpl +import org.jetbrains.kotlinx.dataframe.impl.columns.newColumnWithActualType +import org.jetbrains.kotlinx.dataframe.impl.columns.toColumnSet +import org.jetbrains.kotlinx.dataframe.index +import org.jetbrains.kotlinx.dataframe.nrow +import org.jetbrains.kotlinx.dataframe.type +import org.jetbrains.kotlinx.dataframe.util.ITERABLE_COLUMNS_DEPRECATION_MESSAGE +import kotlin.reflect.KProperty + +public interface SortDsl : ColumnsSelectionDsl { + public fun ColumnSet.desc(): ColumnSet = addFlag(SortFlag.Reversed) + + public fun String.desc(): ColumnSet?> = invoke>().desc() + + public fun KProperty.desc(): ColumnSet = toColumnAccessor().desc() + + public fun ColumnSet.nullsLast(flag: Boolean = true): ColumnSet = + if (flag) addFlag(SortFlag.NullsLast) else this + + public fun String.nullsLast(flag: Boolean = true): ColumnSet?> = + invoke>().nullsLast(flag) + + public fun KProperty.nullsLast(flag: Boolean = true): ColumnSet = toColumnAccessor().nullsLast(flag) +} + +/** + * [SortColumnsSelector] is used to express or select multiple columns to sort by, represented by [ColumnSet]``, + * using the context of [SortDsl]`` as `this` and `it`. + * + * So: + * ```kotlin + * SortDsl.(it: SortDsl) -> ColumnSet + * ``` + */ +public typealias SortColumnsSelector = Selector, ColumnSet> + +// region DataColumn + +public fun > DataColumn.sort(): ValueColumn = + DataColumn.createValueColumn(name, values().sorted(), type, defaultValue = defaultValue()) + +public fun > DataColumn.sortDesc(): ValueColumn = + DataColumn.createValueColumn(name, values().sortedDescending(), type, defaultValue = defaultValue()) + +/** + * ## Sort [DataColumn] With + * + * This function returns the sorted version of the current [ValueColumn], [FrameColumn], or [ColumnGroup] based + * on the given [Comparator]. The [comparator\] can either be given as an instance of [Comparator], or directly + * as a lambda. + * + * #### For example + * + * `df`[`[`][DataFrame.get]`"price"`[`]`][DataFrame.get]`.`[sortWith][sortWith]` { a, b -> a - b }` + * + * + *      + * + * `df.`[select][DataFrame.select]` {` + * + *     `name.`[sortWith][sortWith]`(myComparator) `[and][ColumnsSelectionDsl.and]` `[allAfter][ColumnsSelectionDsl.allAfter]`(name)` + * + * `}` + * + * @receiver The [DataColumn] to sort. This can be either a [ValueColumn], [FrameColumn], or [ColumnGroup] and will + * dictate the return type of the function. + * @param [comparator\] The [Comparator] to use for sorting the [DataColumn]. This can either be a [Comparator]<[T\]> or + * a lambda of type `(`[T][T\]`, `[T][T\]`) -> `[Int][Int]. + * @return The sorted [DataColumn] [this\] of the same type as the receiver. + */ +private interface CommonDataColumnSortWithDocs + +/** ## Sort [DataColumn][org.jetbrains.kotlinx.dataframe.DataColumn] With + * + * This function returns the sorted version of the current [ValueColumn][org.jetbrains.kotlinx.dataframe.columns.ValueColumn], [FrameColumn][org.jetbrains.kotlinx.dataframe.columns.FrameColumn], or [ColumnGroup][org.jetbrains.kotlinx.dataframe.columns.ColumnGroup] based + * on the given [Comparator]. The [comparator] can either be given as an instance of [Comparator], or directly + * as a lambda. + * + * #### For example + * + * `df`[`[`][org.jetbrains.kotlinx.dataframe.DataFrame.get]`"price"`[`]`][org.jetbrains.kotlinx.dataframe.DataFrame.get]`.`[sortWith][org.jetbrains.kotlinx.dataframe.api.sortWith]` { a, b -> a - b }` + * + * + *      + * + * `df.`[select][org.jetbrains.kotlinx.dataframe.DataFrame.select]` {` + * + *     `name.`[sortWith][org.jetbrains.kotlinx.dataframe.api.sortWith]`(myComparator) `[and][org.jetbrains.kotlinx.dataframe.api.ColumnsSelectionDsl.and]` `[allAfter][org.jetbrains.kotlinx.dataframe.api.ColumnsSelectionDsl.allAfter]`(name)` + * + * `}` + * + * @receiver The [DataColumn][org.jetbrains.kotlinx.dataframe.DataColumn] to sort. This can be either a [ValueColumn][org.jetbrains.kotlinx.dataframe.columns.ValueColumn], [FrameColumn][org.jetbrains.kotlinx.dataframe.columns.FrameColumn], or [ColumnGroup][org.jetbrains.kotlinx.dataframe.columns.ColumnGroup] and will + * dictate the return type of the function. + * @param [comparator] The [Comparator] to use for sorting the [DataColumn][org.jetbrains.kotlinx.dataframe.DataColumn]. This can either be a [Comparator]<[T]> or + * a lambda of type `(`[T][T]`, `[T][T]`) -> `[Int][Int]. + * @return The sorted [DataColumn][org.jetbrains.kotlinx.dataframe.DataColumn] [this] of the same type as the receiver. */ +public fun > C.sortWith(comparator: Comparator): C = + DataColumn.create(name, values().sortedWith(comparator), type) as C + +/** ## Sort [DataColumn][org.jetbrains.kotlinx.dataframe.DataColumn] With + * + * This function returns the sorted version of the current [ValueColumn][org.jetbrains.kotlinx.dataframe.columns.ValueColumn], [FrameColumn][org.jetbrains.kotlinx.dataframe.columns.FrameColumn], or [ColumnGroup][org.jetbrains.kotlinx.dataframe.columns.ColumnGroup] based + * on the given [Comparator]. The [comparator] can either be given as an instance of [Comparator], or directly + * as a lambda. + * + * #### For example + * + * `df`[`[`][org.jetbrains.kotlinx.dataframe.DataFrame.get]`"price"`[`]`][org.jetbrains.kotlinx.dataframe.DataFrame.get]`.`[sortWith][org.jetbrains.kotlinx.dataframe.api.sortWith]` { a, b -> a - b }` + * + * + *      + * + * `df.`[select][org.jetbrains.kotlinx.dataframe.DataFrame.select]` {` + * + *     `name.`[sortWith][org.jetbrains.kotlinx.dataframe.api.sortWith]`(myComparator) `[and][org.jetbrains.kotlinx.dataframe.api.ColumnsSelectionDsl.and]` `[allAfter][org.jetbrains.kotlinx.dataframe.api.ColumnsSelectionDsl.allAfter]`(name)` + * + * `}` + * + * @receiver The [DataColumn][org.jetbrains.kotlinx.dataframe.DataColumn] to sort. This can be either a [ValueColumn][org.jetbrains.kotlinx.dataframe.columns.ValueColumn], [FrameColumn][org.jetbrains.kotlinx.dataframe.columns.FrameColumn], or [ColumnGroup][org.jetbrains.kotlinx.dataframe.columns.ColumnGroup] and will + * dictate the return type of the function. + * @param [comparator] The [Comparator] to use for sorting the [DataColumn][org.jetbrains.kotlinx.dataframe.DataColumn]. This can either be a [Comparator]<[T]> or + * a lambda of type `(`[T][T]`, `[T][T]`) -> `[Int][Int]. + * @return The sorted [DataColumn][org.jetbrains.kotlinx.dataframe.DataColumn] [this] of the same type as the receiver. */ +public fun > C.sortWith(comparator: (T, T) -> Int): C = + sortWith(Comparator(comparator)) + +// endregion + +// region DataFrame + +public fun DataFrame.sortBy(columns: SortColumnsSelector): DataFrame = sortByImpl( + UnresolvedColumnsPolicy.Fail, columns +) + +@Deprecated( + message = ITERABLE_COLUMNS_DEPRECATION_MESSAGE, + replaceWith = ReplaceWith( + "sortBy { cols.toColumnSet() }", + "org.jetbrains.kotlinx.dataframe.impl.columns.toColumnSet" + ), + level = DeprecationLevel.ERROR +) +public fun DataFrame.sortBy(cols: Iterable?>>): DataFrame = + sortBy { cols.toColumnSet() } + +public fun DataFrame.sortBy(vararg cols: ColumnReference?>): DataFrame = + sortBy { cols.toColumnSet() } + +public fun DataFrame.sortBy(vararg cols: String): DataFrame = sortBy { cols.toColumnSet() } + +public fun DataFrame.sortBy(vararg cols: KProperty?>): DataFrame = sortBy { cols.toColumnSet() } + +public fun DataFrame.sortWith(comparator: Comparator>): DataFrame { + val permutation = rows().sortedWith(comparator).map { it.index } + return this[permutation] +} + +public fun DataFrame.sortWith(comparator: (DataRow, DataRow) -> Int): DataFrame = + sortWith(Comparator(comparator)) + +public fun DataFrame.sortByDesc(columns: SortColumnsSelector): DataFrame { + val set = columns.toColumnSet() + return sortByImpl { set.desc() } +} + +public fun DataFrame.sortByDesc(vararg columns: KProperty?>): DataFrame = + sortByDesc { columns.toColumnSet() } + +public fun DataFrame.sortByDesc(vararg columns: String): DataFrame = sortByDesc { columns.toColumnSet() } + +public fun DataFrame.sortByDesc(vararg columns: ColumnReference?>): DataFrame = + sortByDesc { columns.toColumnSet() } + +@Deprecated( + message = ITERABLE_COLUMNS_DEPRECATION_MESSAGE, + replaceWith = ReplaceWith( + "sortByDesc { columns.toColumnSet() }", + "org.jetbrains.kotlinx.dataframe.columns.toColumnSet", + ), + level = DeprecationLevel.ERROR, +) +public fun DataFrame.sortByDesc(columns: Iterable?>>): DataFrame = + sortByDesc { columns.toColumnSet() } + +// endregion + +// region GroupBy + +public fun GroupBy.sortBy(vararg cols: String): GroupBy = sortBy { cols.toColumnSet() } + +public fun GroupBy.sortBy(vararg cols: ColumnReference?>): GroupBy = + sortBy { cols.toColumnSet() } + +public fun GroupBy.sortBy(vararg cols: KProperty?>): GroupBy = + sortBy { cols.toColumnSet() } + +public fun GroupBy.sortBy(selector: SortColumnsSelector): GroupBy = sortByImpl(selector) + +public fun GroupBy.sortByDesc(vararg cols: String): GroupBy = sortByDesc { cols.toColumnSet() } + +public fun GroupBy.sortByDesc(vararg cols: ColumnReference?>): GroupBy = + sortByDesc { cols.toColumnSet() } + +public fun GroupBy.sortByDesc(vararg cols: KProperty?>): GroupBy = + sortByDesc { cols.toColumnSet() } + +public fun GroupBy.sortByDesc(selector: SortColumnsSelector): GroupBy { + val set = selector.toColumnSet() + return sortByImpl { set.desc() } +} + +private fun GroupBy.createColumnFromGroupExpression( + receiver: ColumnsSelectionDsl, + expression: DataFrameExpression, +): DataColumn { + return receiver.newColumnWithActualType("") { row -> + val group = row[groups] + expression(group, group) + } +} + +public fun GroupBy.sortByGroup( + nullsLast: Boolean = false, + expression: DataFrameExpression, +): GroupBy = toDataFrame().sortBy { + createColumnFromGroupExpression(this, expression).nullsLast(nullsLast) +}.asGroupBy(groups) + +public fun GroupBy.sortByGroupDesc( + nullsLast: Boolean = false, + expression: DataFrameExpression, +): GroupBy = toDataFrame().sortBy { + createColumnFromGroupExpression(this, expression).desc().nullsLast(nullsLast) +}.asGroupBy(groups) + +public fun GroupBy.sortByCountAsc(): GroupBy = sortByGroup { nrow } + +public fun GroupBy.sortByCount(): GroupBy = sortByGroupDesc { nrow } + +public fun GroupBy.sortByKeyDesc(nullsLast: Boolean = false): GroupBy = toDataFrame() + .sortBy { keys.columns().toColumnSet().desc().nullsLast(nullsLast) }.asGroupBy(groups) + +public fun GroupBy.sortByKey(nullsLast: Boolean = false): GroupBy = toDataFrame() + .sortBy { keys.columns().toColumnSet().nullsLast(nullsLast) }.asGroupBy(groups) + +// endregion diff --git a/core/generated-sources/src/test/kotlin/org/jetbrains/kotlinx/dataframe/api/sort.kt b/core/generated-sources/src/test/kotlin/org/jetbrains/kotlinx/dataframe/api/sort.kt new file mode 100644 index 0000000000..a04dc3f8fd --- /dev/null +++ b/core/generated-sources/src/test/kotlin/org/jetbrains/kotlinx/dataframe/api/sort.kt @@ -0,0 +1,70 @@ +package org.jetbrains.kotlinx.dataframe.api + +import io.kotest.matchers.shouldBe +import org.jetbrains.kotlinx.dataframe.DataColumn +import org.jetbrains.kotlinx.dataframe.nrow +import org.junit.Test + +class SortDataColumn { + + @Test + fun `value column sort with`() { + val col = DataColumn.createValueColumn("", listOf(1, 6, 8, 4, 2, 9)) + val sortedCol = col.sort() + val descSortedCol = col.sortDesc() + + col.sortWith { a, b -> a - b } shouldBe sortedCol + col.sortWith { a, b -> b - a } shouldBe descSortedCol + + col.sortWith(Int::compareTo) shouldBe sortedCol + col.sortWith(Comparator(Int::compareTo)) shouldBe sortedCol + } + + @Test + fun `frame column sort with`() { + val col = DataColumn.createFrameColumn( + "", + listOf( + dataFrameOf("a")(1, 2), + dataFrameOf("a")(1), + dataFrameOf("a")(1, 2, 3) + ) + ) + val sortedCol = DataColumn.createFrameColumn( + "", + listOf( + dataFrameOf("a")(1), + dataFrameOf("a")(1, 2), + dataFrameOf("a")(1, 2, 3) + ) + ) + + col.sortWith { df1, df2 -> df1.nrow - df2.nrow } shouldBe sortedCol + col.sortWith(Comparator { df1, df2 -> df1.nrow - df2.nrow }) shouldBe sortedCol + } + + @Test + fun `column group sort with`() { + val a by column() + val b by column() + + val col = DataColumn.createColumnGroup( + "", + dataFrameOf( + columnOf(1, 3, 2) named a, + columnOf("hello", "world", "!") named b, + ), + ) + + val sortedCol = DataColumn.createColumnGroup( + "", + dataFrameOf( + columnOf(1, 2, 3) named a, + columnOf("hello", "!", "world") named b, + ), + ) + + col.sortWith { df1, df2 -> df1[a] - df2[a] } shouldBe sortedCol + col.sortWith(Comparator { df1, df2 -> df1[a] - df2[a] }) shouldBe sortedCol + } +} From d66323a3c02a967c69e7208c60f2ff2137ee551c Mon Sep 17 00:00:00 2001 From: Jolan Rensen Date: Mon, 24 Jul 2023 17:45:55 +0200 Subject: [PATCH 05/45] added deprecation messages instructions to RELEASE_CHECK_LIST.md and updated the file with regions and hints to when a feature will be removed --- RELEASE_CHECK_LIST.md | 5 ++++ .../dataframe/util/deprecationMessages.kt | 24 +++++++++++++++---- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/RELEASE_CHECK_LIST.md b/RELEASE_CHECK_LIST.md index 0665b64cb1..2b3c8e1e24 100644 --- a/RELEASE_CHECK_LIST.md +++ b/RELEASE_CHECK_LIST.md @@ -29,3 +29,8 @@ 17. Create Release from the release tag on GitHub 18. Update a KDF version in the [Kotlin Jupyter Descriptor](https://github.com/Kotlin/kotlin-jupyter-libraries/blob/master/dataframe.json). Now the Renovate bot doing this 19. Update DataFrame version in gradle.properties file for next release cycle (i.e. 0.10.0 -> 0.11.0) +20. Update deprecated functions in [deprecationMessages.kt](/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/util/deprecationMessages.kt) + such that + - `Level.WARNING` messages are changed to `Level.ERROR` + - `Level.ERROR` messages and their functions are removed. + - Update regions in the file accordingly. diff --git a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/util/deprecationMessages.kt b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/util/deprecationMessages.kt index aabe39112a..6709c0e4fc 100644 --- a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/util/deprecationMessages.kt +++ b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/util/deprecationMessages.kt @@ -1,13 +1,29 @@ package org.jetbrains.kotlinx.dataframe.util -internal const val DF_READ_DEPRECATION_MESSAGE = "Replaced with `unfold` operation." +/* + * This file contains deprecation messages for the whole core module. + * After each release, all messages should be reviewed and updated. + * Level.WARNING -> Level.ERROR + * Level.ERROR -> Remove + */ +// region WARNING in 0.10.0, ERROR in 0.11.0 + +internal const val DF_READ_DEPRECATION_MESSAGE = "Replaced with `unfold` operation. Removed in 0.11.0." internal const val DF_READ_REPLACE_MESSAGE = "this.unfold(*columns)" -internal const val ITERABLE_COLUMNS_DEPRECATION_MESSAGE = "Replaced with `toColumnSet()` operation." +internal const val ITERABLE_COLUMNS_DEPRECATION_MESSAGE = "Replaced with `toColumnSet()` operation. Removed in 0.11.0." -internal const val DIFF_DEPRECATION_MESSAGE = "Replaced to explicitly indicate nullable return value; added a new non-null overload." +// endregion -internal const val DIFF_REPLACE_MESSAGE = "this.diffOrNull(expression)" +// region WARNING in 0.11.0, ERROR in 0.12.0 +internal const val DIFF_DEPRECATION_MESSAGE = "Replaced to explicitly indicate nullable return value; added a new non-null overload. Will be removed in 0.12.0." +internal const val DIFF_REPLACE_MESSAGE = "this.diffOrNull(expression)" internal const val DIFF_OR_NULL_IMPORT = "org.jetbrains.kotlinx.dataframe.api.diffOrNull" + +// endregion + +// region WARNING in 0.12.0, ERROR in 0.13.0 + +// endregion From e9640a5af78997eb983e3ab9c9eca24075e93b9e Mon Sep 17 00:00:00 2001 From: Jolan Rensen Date: Tue, 25 Jul 2023 13:08:44 +0200 Subject: [PATCH 06/45] added update deprecation messages to central file --- .../jetbrains/kotlinx/dataframe/api/update.kt | 13 +++++--- .../dataframe/util/deprecationMessages.kt | 30 ++++++++++++++++--- .../jetbrains/kotlinx/dataframe/api/update.kt | 13 +++++--- .../dataframe/util/deprecationMessages.kt | 6 ++++ 4 files changed, 50 insertions(+), 12 deletions(-) diff --git a/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/update.kt b/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/update.kt index dbed59ac10..cb335c9d2a 100644 --- a/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/update.kt +++ b/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/update.kt @@ -12,6 +12,10 @@ import org.jetbrains.kotlinx.dataframe.impl.api.updateImpl import org.jetbrains.kotlinx.dataframe.impl.api.updateWithValuePerColumnImpl import org.jetbrains.kotlinx.dataframe.impl.headPlusArray import org.jetbrains.kotlinx.dataframe.util.ITERABLE_COLUMNS_DEPRECATION_MESSAGE +import org.jetbrains.kotlinx.dataframe.util.UPDATE_AS_NULLABLE_MESSAGE +import org.jetbrains.kotlinx.dataframe.util.UPDATE_AS_NULLABLE_REPLACE +import org.jetbrains.kotlinx.dataframe.util.UPDATE_WITH_VALUE +import org.jetbrains.kotlinx.dataframe.util.UPDATE_WITH_VALUE_REPLACE import kotlin.reflect.KProperty /** @@ -403,8 +407,9 @@ public fun Update>.asFrame(expression: DataFrameExpressi asFrameImpl(expression) @Deprecated( - "Useless unless in combination with `withValue(null)`, but then users can just use `with { null }`...", - ReplaceWith("this as Update") + UPDATE_AS_NULLABLE_MESSAGE, + ReplaceWith(UPDATE_AS_NULLABLE_REPLACE), + DeprecationLevel.WARNING, ) public fun Update.asNullable(): Update = this as Update @@ -752,7 +757,7 @@ public fun Update.withNull(): DataFrame = with { null } public fun Update.withZero(): DataFrame = updateWithValuePerColumnImpl { 0 as C } /** - * ## With Value + * ## With Value (Deprecated) * Specific version of [with][org.jetbrains.kotlinx.dataframe.api.with] that simply sets the value of each selected row to [value]. * * For example: @@ -763,5 +768,5 @@ public fun Update.withZero(): DataFrame = updateWithValuePerColu * * @param [value] The value to set the selected rows to. In contrast to [with][Update.with], this must be the same exact type. */ -@Deprecated("Use with { value } instead", ReplaceWith("this.with { value }")) +@Deprecated(UPDATE_WITH_VALUE, ReplaceWith(UPDATE_WITH_VALUE_REPLACE), DeprecationLevel.WARNING) public fun Update.withValue(value: C): DataFrame = with { value } diff --git a/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/util/deprecationMessages.kt b/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/util/deprecationMessages.kt index aabe39112a..f3f3016be5 100644 --- a/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/util/deprecationMessages.kt +++ b/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/util/deprecationMessages.kt @@ -1,13 +1,35 @@ package org.jetbrains.kotlinx.dataframe.util -internal const val DF_READ_DEPRECATION_MESSAGE = "Replaced with `unfold` operation." +/* + * This file contains deprecation messages for the whole core module. + * After each release, all messages should be reviewed and updated. + * Level.WARNING -> Level.ERROR + * Level.ERROR -> Remove + */ +// region WARNING in 0.10.0, ERROR in 0.11.0 + +internal const val DF_READ_DEPRECATION_MESSAGE = "Replaced with `unfold` operation. Removed in 0.11.0." internal const val DF_READ_REPLACE_MESSAGE = "this.unfold(*columns)" -internal const val ITERABLE_COLUMNS_DEPRECATION_MESSAGE = "Replaced with `toColumnSet()` operation." +internal const val ITERABLE_COLUMNS_DEPRECATION_MESSAGE = "Replaced with `toColumnSet()` operation. Removed in 0.11.0." -internal const val DIFF_DEPRECATION_MESSAGE = "Replaced to explicitly indicate nullable return value; added a new non-null overload." +// endregion -internal const val DIFF_REPLACE_MESSAGE = "this.diffOrNull(expression)" +// region WARNING in 0.11.0, ERROR in 0.12.0 +internal const val DIFF_DEPRECATION_MESSAGE = "Replaced to explicitly indicate nullable return value; added a new non-null overload. Will be removed in 0.12.0." +internal const val DIFF_REPLACE_MESSAGE = "this.diffOrNull(expression)" internal const val DIFF_OR_NULL_IMPORT = "org.jetbrains.kotlinx.dataframe.api.diffOrNull" + +internal const val UPDATE_AS_NULLABLE_MESSAGE = "This function is useless unless in combination with `withValue(null)`, but then you can just use `with { null }`. Will be removed in 0.12.0." +internal const val UPDATE_AS_NULLABLE_REPLACE = "this as Update" + +internal const val UPDATE_WITH_VALUE = "Replaced in favor of `with { value }`. Will be removed in 0.12.0." +internal const val UPDATE_WITH_VALUE_REPLACE = "this.with { value }" + +// endregion + +// region WARNING in 0.12.0, ERROR in 0.13.0 + +// endregion diff --git a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/update.kt b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/update.kt index 8cddfeaf0a..fa4ed2dfeb 100644 --- a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/update.kt +++ b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/update.kt @@ -12,6 +12,10 @@ import org.jetbrains.kotlinx.dataframe.impl.api.updateImpl import org.jetbrains.kotlinx.dataframe.impl.api.updateWithValuePerColumnImpl import org.jetbrains.kotlinx.dataframe.impl.headPlusArray import org.jetbrains.kotlinx.dataframe.util.ITERABLE_COLUMNS_DEPRECATION_MESSAGE +import org.jetbrains.kotlinx.dataframe.util.UPDATE_AS_NULLABLE_MESSAGE +import org.jetbrains.kotlinx.dataframe.util.UPDATE_AS_NULLABLE_REPLACE +import org.jetbrains.kotlinx.dataframe.util.UPDATE_WITH_VALUE +import org.jetbrains.kotlinx.dataframe.util.UPDATE_WITH_VALUE_REPLACE import kotlin.reflect.KProperty /** @@ -247,8 +251,9 @@ public fun Update>.asFrame(expression: DataFrameExpressi asFrameImpl(expression) @Deprecated( - "Useless unless in combination with `withValue(null)`, but then users can just use `with { null }`...", - ReplaceWith("this as Update") + UPDATE_AS_NULLABLE_MESSAGE, + ReplaceWith(UPDATE_AS_NULLABLE_REPLACE), + DeprecationLevel.WARNING, ) public fun Update.asNullable(): Update = this as Update @@ -445,12 +450,12 @@ public fun Update.withNull(): DataFrame = with { null } public fun Update.withZero(): DataFrame = updateWithValuePerColumnImpl { 0 as C } /** - * ## With Value + * ## With Value (Deprecated) * @include [CommonSpecificWithDoc] * {@arg [CommonSpecificWithDocFirstArg] [value]} * {@arg [CommonSpecificWithDocSecondArg] [withValue][withValue]`(-1)} * * @param [value] The value to set the selected rows to. In contrast to [with][Update.with], this must be the same exact type. */ -@Deprecated("Use with { value } instead", ReplaceWith("this.with { value }")) +@Deprecated(UPDATE_WITH_VALUE, ReplaceWith(UPDATE_WITH_VALUE_REPLACE), DeprecationLevel.WARNING) public fun Update.withValue(value: C): DataFrame = with { value } diff --git a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/util/deprecationMessages.kt b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/util/deprecationMessages.kt index 6709c0e4fc..f3f3016be5 100644 --- a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/util/deprecationMessages.kt +++ b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/util/deprecationMessages.kt @@ -22,6 +22,12 @@ internal const val DIFF_DEPRECATION_MESSAGE = "Replaced to explicitly indicate n internal const val DIFF_REPLACE_MESSAGE = "this.diffOrNull(expression)" internal const val DIFF_OR_NULL_IMPORT = "org.jetbrains.kotlinx.dataframe.api.diffOrNull" +internal const val UPDATE_AS_NULLABLE_MESSAGE = "This function is useless unless in combination with `withValue(null)`, but then you can just use `with { null }`. Will be removed in 0.12.0." +internal const val UPDATE_AS_NULLABLE_REPLACE = "this as Update" + +internal const val UPDATE_WITH_VALUE = "Replaced in favor of `with { value }`. Will be removed in 0.12.0." +internal const val UPDATE_WITH_VALUE_REPLACE = "this.with { value }" + // endregion // region WARNING in 0.12.0, ERROR in 0.13.0 From e1200e997b46344a2e96ac3ad26440eca6098110 Mon Sep 17 00:00:00 2001 From: Jolan Rensen Date: Tue, 25 Jul 2023 14:59:47 +0200 Subject: [PATCH 07/45] made removed in x.x.x general too --- .../dataframe/util/deprecationMessages.kt | 16 +++++++++++----- .../dataframe/util/deprecationMessages.kt | 16 +++++++++++----- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/util/deprecationMessages.kt b/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/util/deprecationMessages.kt index f3f3016be5..3acb2d2d67 100644 --- a/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/util/deprecationMessages.kt +++ b/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/util/deprecationMessages.kt @@ -9,27 +9,33 @@ package org.jetbrains.kotlinx.dataframe.util // region WARNING in 0.10.0, ERROR in 0.11.0 -internal const val DF_READ_DEPRECATION_MESSAGE = "Replaced with `unfold` operation. Removed in 0.11.0." +private const val message_0_11_0 = "Was removed in 0.11.0." + +internal const val DF_READ_DEPRECATION_MESSAGE = "Replaced with `unfold` operation. $message_0_11_0" internal const val DF_READ_REPLACE_MESSAGE = "this.unfold(*columns)" -internal const val ITERABLE_COLUMNS_DEPRECATION_MESSAGE = "Replaced with `toColumnSet()` operation. Removed in 0.11.0." +internal const val ITERABLE_COLUMNS_DEPRECATION_MESSAGE = "Replaced with `toColumnSet()` operation. $message_0_11_0" // endregion // region WARNING in 0.11.0, ERROR in 0.12.0 -internal const val DIFF_DEPRECATION_MESSAGE = "Replaced to explicitly indicate nullable return value; added a new non-null overload. Will be removed in 0.12.0." +private const val message_0_12_0 = "Will be removed in 0.12.0." + +internal const val DIFF_DEPRECATION_MESSAGE = "Replaced to explicitly indicate nullable return value; added a new non-null overload. $message_0_12_0" internal const val DIFF_REPLACE_MESSAGE = "this.diffOrNull(expression)" internal const val DIFF_OR_NULL_IMPORT = "org.jetbrains.kotlinx.dataframe.api.diffOrNull" -internal const val UPDATE_AS_NULLABLE_MESSAGE = "This function is useless unless in combination with `withValue(null)`, but then you can just use `with { null }`. Will be removed in 0.12.0." +internal const val UPDATE_AS_NULLABLE_MESSAGE = "This function is useless unless in combination with `withValue(null)`, but then you can just use `with { null }`. $message_0_12_0" internal const val UPDATE_AS_NULLABLE_REPLACE = "this as Update" -internal const val UPDATE_WITH_VALUE = "Replaced in favor of `with { value }`. Will be removed in 0.12.0." +internal const val UPDATE_WITH_VALUE = "Replaced in favor of `with { value }`. $message_0_12_0" internal const val UPDATE_WITH_VALUE_REPLACE = "this.with { value }" // endregion // region WARNING in 0.12.0, ERROR in 0.13.0 +private const val message_0_13_0 = "Will be removed in 0.13.0." + // endregion diff --git a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/util/deprecationMessages.kt b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/util/deprecationMessages.kt index f3f3016be5..3acb2d2d67 100644 --- a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/util/deprecationMessages.kt +++ b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/util/deprecationMessages.kt @@ -9,27 +9,33 @@ package org.jetbrains.kotlinx.dataframe.util // region WARNING in 0.10.0, ERROR in 0.11.0 -internal const val DF_READ_DEPRECATION_MESSAGE = "Replaced with `unfold` operation. Removed in 0.11.0." +private const val message_0_11_0 = "Was removed in 0.11.0." + +internal const val DF_READ_DEPRECATION_MESSAGE = "Replaced with `unfold` operation. $message_0_11_0" internal const val DF_READ_REPLACE_MESSAGE = "this.unfold(*columns)" -internal const val ITERABLE_COLUMNS_DEPRECATION_MESSAGE = "Replaced with `toColumnSet()` operation. Removed in 0.11.0." +internal const val ITERABLE_COLUMNS_DEPRECATION_MESSAGE = "Replaced with `toColumnSet()` operation. $message_0_11_0" // endregion // region WARNING in 0.11.0, ERROR in 0.12.0 -internal const val DIFF_DEPRECATION_MESSAGE = "Replaced to explicitly indicate nullable return value; added a new non-null overload. Will be removed in 0.12.0." +private const val message_0_12_0 = "Will be removed in 0.12.0." + +internal const val DIFF_DEPRECATION_MESSAGE = "Replaced to explicitly indicate nullable return value; added a new non-null overload. $message_0_12_0" internal const val DIFF_REPLACE_MESSAGE = "this.diffOrNull(expression)" internal const val DIFF_OR_NULL_IMPORT = "org.jetbrains.kotlinx.dataframe.api.diffOrNull" -internal const val UPDATE_AS_NULLABLE_MESSAGE = "This function is useless unless in combination with `withValue(null)`, but then you can just use `with { null }`. Will be removed in 0.12.0." +internal const val UPDATE_AS_NULLABLE_MESSAGE = "This function is useless unless in combination with `withValue(null)`, but then you can just use `with { null }`. $message_0_12_0" internal const val UPDATE_AS_NULLABLE_REPLACE = "this as Update" -internal const val UPDATE_WITH_VALUE = "Replaced in favor of `with { value }`. Will be removed in 0.12.0." +internal const val UPDATE_WITH_VALUE = "Replaced in favor of `with { value }`. $message_0_12_0" internal const val UPDATE_WITH_VALUE_REPLACE = "this.with { value }" // endregion // region WARNING in 0.12.0, ERROR in 0.13.0 +private const val message_0_13_0 = "Will be removed in 0.13.0." + // endregion From 299d1af554600e8ace02bb85b9effc19a4d30b6e Mon Sep 17 00:00:00 2001 From: Jolan Rensen Date: Wed, 26 Jul 2023 14:33:52 +0200 Subject: [PATCH 08/45] updated gh action to include sitemap.xml using help of Svetlana --- .github/workflows/main.yml | 29 +- .github/writerside-build/Dockerfile | 10 - .github/writerside-build/action.yml | 6 - .github/writerside-build/entrypoint.sh | 6 - docs/StardustDocs/sitemap.xml | 717 +++++++++++++++++++++++++ 5 files changed, 741 insertions(+), 27 deletions(-) delete mode 100644 .github/writerside-build/Dockerfile delete mode 100644 .github/writerside-build/action.yml delete mode 100644 .github/writerside-build/entrypoint.sh create mode 100644 docs/StardustDocs/sitemap.xml diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index d2c17f7509..9553a3e151 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,8 +1,10 @@ name: Build docs on: + # Specify to run a workflow manually from the Actions tab on GitHub. workflow_dispatch: +# Gives the workflow permissions to clone the repo and create a page deployment permissions: id-token: write pages: write @@ -20,15 +22,31 @@ env: jobs: build-job: runs-on: ubuntu-latest + container: registry.jetbrains.team/p/writerside/builder/writerside-builder:2.1.1485-p3896 + outputs: + artifact: ${{ steps.generate-artifact.outputs.artifact }} steps: - name: Checkout repository uses: actions/checkout@v3 - - name: Build Writerside docs using Docker - uses: ./.github/writerside-build - - name: Upload artifact + - name: Prepare for build + run: | + apt-get update + apt-get install -y zip + mkdir -p artifacts + - name: Build docs and include sitemap.xml + run: | + export DISPLAY=:99 + Xvfb :99 & + /opt/builder/bin/idea.sh helpbuilderinspect -source-dir . -product $PRODUCT --runner github -output-dir artifacts/ || true + test -e artifacts/$ARTIFACT && echo $ARTIFACT exists + cp docs/StardustDocs/sitemap.xml artifacts/sitemap.xml + cd artifacts + zip -r $ARTIFACT sitemap.xml + working-directory: ${{ github.workspace }} + - name: Upload modified documentation artifact uses: actions/upload-artifact@v3 with: - name: artifact + name: help path: artifacts/${{ env.ARTIFACT }} retention-days: 7 - name: Upload algolia-indexes @@ -42,13 +60,14 @@ jobs: environment: name: github-pages url: ${{ steps.deployment.outputs.page_url }} + # Requires the build-job results needs: build-job runs-on: ubuntu-latest steps: - name: Download artifact uses: actions/download-artifact@v3 with: - name: artifact + name: help - name: Unzip artifact uses: montudor/action-zip@v1 with: diff --git a/.github/writerside-build/Dockerfile b/.github/writerside-build/Dockerfile deleted file mode 100644 index d48e3f09b9..0000000000 --- a/.github/writerside-build/Dockerfile +++ /dev/null @@ -1,10 +0,0 @@ -# Container image that runs your code -FROM registry.jetbrains.team/p/writerside/builder/writerside-builder:2.1.1256-p3333 - -# Copies your code file from your action repository to the filesystem path `/` of the container -COPY entrypoint.sh /entrypoint.sh - -RUN chmod +x /entrypoint.sh - -# Code file to execute when the docker container starts up (`entrypoint.sh`) -ENTRYPOINT ["/entrypoint.sh"] diff --git a/.github/writerside-build/action.yml b/.github/writerside-build/action.yml deleted file mode 100644 index 80367d1b13..0000000000 --- a/.github/writerside-build/action.yml +++ /dev/null @@ -1,6 +0,0 @@ -name: Build Writerside docs using Docker -description: Build Writerside documentation artifacts - -runs: - using: 'docker' - image: 'Dockerfile' diff --git a/.github/writerside-build/entrypoint.sh b/.github/writerside-build/entrypoint.sh deleted file mode 100644 index 33eb48a7f8..0000000000 --- a/.github/writerside-build/entrypoint.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash - -set -e -/opt/builder/bin/idea.sh helpbuilderinspect -source-dir . -product $PRODUCT --runner github -output-dir artifacts/ || true -echo "Test existing of $ARTIFACT artifact" -test -e artifacts/$ARTIFACT diff --git a/docs/StardustDocs/sitemap.xml b/docs/StardustDocs/sitemap.xml new file mode 100644 index 0000000000..95bde29c87 --- /dev/null +++ b/docs/StardustDocs/sitemap.xml @@ -0,0 +1,717 @@ + + + + + + + https://kotlin.github.io/dataframe/ + 2023-06-26T12:33:14+00:00 + 1.00 + + + https://kotlin.github.io/dataframe/overview.html + 2023-06-26T12:33:14+00:00 + 0.80 + + + https://kotlin.github.io/dataframe/operations.html + 2023-06-26T12:33:14+00:00 + 0.64 + + + https://kotlin.github.io/dataframe/hierarchical.html + 2023-06-26T12:33:14+00:00 + 0.64 + + + https://kotlin.github.io/dataframe/collectionsinterop.html + 2023-06-26T12:33:14+00:00 + 0.64 + + + https://kotlin.github.io/dataframe/extensionpropertiesapi.html + 2023-06-26T12:33:14+00:00 + 0.64 + + + https://kotlin.github.io/dataframe/dataframe.html + 2023-06-26T12:33:14+00:00 + 0.64 + + + https://kotlin.github.io/dataframe/schemas.html + 2023-06-26T12:33:14+00:00 + 0.64 + + + https://kotlin.github.io/dataframe/gettingstartedgradleadvanced.html + 2023-06-26T12:33:14+00:00 + 0.64 + + + https://kotlin.github.io/dataframe/apilevels.html + 2023-06-26T12:33:14+00:00 + 0.64 + + + https://kotlin.github.io/dataframe/filter.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/select.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/columnselectors.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/move.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/group.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/split.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/merge.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/gather.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/groupby.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/rename.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/datarow.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/update.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/convert.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/replace.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/pivot.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/summarystatistics.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/add.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/append.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/columns.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/columnnames.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/columntypes.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/columnscount.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/concat.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/corr.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/count.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/countdistinct.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/cumsum.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/describe.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/distinct.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/drop.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/slicerows.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/duplicate.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/explode.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/fill.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/first.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/flatten.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/iterate.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/format.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/getcolumn.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/datacolumn.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/head.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/implode.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/infertype.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/insert.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/join.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/last.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/map.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/minmax.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/mean.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/median.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/parse.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/remove.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/reorder.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/reverse.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/rows.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/rowscount.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/schema.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/shuffle.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/single.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/sortby.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/std.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/sum.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/tolist.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/tomap.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/unfold.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/ungroup.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/values.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/valuecounts.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/xs.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/nanandna.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/create.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/read.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/createdataframe.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/modify.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/schemasgradle.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/gettingstartedjupyternotebook.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/kpropertiesapi.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/info.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/access.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/multipledataframes.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/types.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/schemasjupyter.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/schemasinheritance.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/schemascustom.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/schemasexternaljupyter.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/schemasimportopenapigradle.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/schemasimportopenapijupyter.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/gettingstarteddatalore.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/stringapi.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/columnaccessorsapi.html + 2023-06-26T12:33:14+00:00 + 0.51 + + + https://kotlin.github.io/dataframe/filterrows.html + 2023-06-26T12:33:14+00:00 + 0.41 + + + https://kotlin.github.io/dataframe/indexing.html + 2023-06-26T12:33:14+00:00 + 0.41 + + + https://kotlin.github.io/dataframe/datetimecolumns.html + 2023-06-26T12:33:14+00:00 + 0.41 + + + https://kotlin.github.io/dataframe/moverename.html + 2023-06-26T12:33:14+00:00 + 0.41 + + + https://kotlin.github.io/dataframe/groupungroupflatten.html + 2023-06-26T12:33:14+00:00 + 0.41 + + + https://kotlin.github.io/dataframe/splitmerge.html + 2023-06-26T12:33:14+00:00 + 0.41 + + + https://kotlin.github.io/dataframe/addremove.html + 2023-06-26T12:33:14+00:00 + 0.41 + + + https://kotlin.github.io/dataframe/appendduplicate.html + 2023-06-26T12:33:14+00:00 + 0.41 + + + https://kotlin.github.io/dataframe/groupbyconcat.html + 2023-06-26T12:33:14+00:00 + 0.41 + + + https://kotlin.github.io/dataframe/updateconvert.html + 2023-06-26T12:33:14+00:00 + 0.41 + + + https://kotlin.github.io/dataframe/explodeimplode.html + 2023-06-26T12:33:14+00:00 + 0.41 + + + https://kotlin.github.io/dataframe/pivotgather.html + 2023-06-26T12:33:14+00:00 + 0.41 + + + https://kotlin.github.io/dataframe/convertto.html + 2023-06-26T12:33:14+00:00 + 0.41 + + + https://kotlin.github.io/dataframe/getcolumns.html + 2023-06-26T12:33:14+00:00 + 0.41 + + + https://kotlin.github.io/dataframe/statisticalrelationship.html + 2023-06-26T12:33:14+00:00 + 0.41 + + + https://kotlin.github.io/dataframe/rowstats.html + 2023-06-26T12:33:14+00:00 + 0.41 + + + https://kotlin.github.io/dataframe/cumulativestatistics.html + 2023-06-26T12:33:14+00:00 + 0.41 + + + https://kotlin.github.io/dataframe/reorderrows.html + 2023-06-26T12:33:14+00:00 + 0.41 + + + https://kotlin.github.io/dataframe/adjustschema.html + 2023-06-26T12:33:14+00:00 + 0.41 + + + https://kotlin.github.io/dataframe/insertreplace.html + 2023-06-26T12:33:14+00:00 + 0.41 + + + https://kotlin.github.io/dataframe/getrow.html + 2023-06-26T12:33:14+00:00 + 0.41 + + + https://kotlin.github.io/dataframe/tohtml.html + 2023-06-26T12:33:14+00:00 + 0.41 + + + https://kotlin.github.io/dataframe/jupyterrendering.html + 2023-06-26T12:33:14+00:00 + 0.41 + + + https://kotlin.github.io/dataframe/getvalues.html + 2023-06-26T12:33:14+00:00 + 0.41 + + + https://kotlin.github.io/dataframe/createcolumn.html + 2023-06-26T12:33:14+00:00 + 0.41 + + + https://kotlin.github.io/dataframe/concatdf.html + 2023-06-26T12:33:14+00:00 + 0.41 + + + https://kotlin.github.io/dataframe/columnoperations.html + 2023-06-26T12:33:14+00:00 + 0.41 + + + https://kotlin.github.io/dataframe/minby.html + 2023-06-26T12:33:14+00:00 + 0.41 + + + https://kotlin.github.io/dataframe/rendering.html + 2023-06-26T12:33:14+00:00 + 0.41 + + + https://kotlin.github.io/dataframe/io.html + 2023-06-26T12:33:14+00:00 + 0.41 + + + https://kotlin.github.io/dataframe/write.html + 2023-06-26T12:33:14+00:00 + 0.41 + + + https://kotlin.github.io/dataframe/gradlereference.html + 2023-06-26T12:33:14+00:00 + 0.41 + + + https://kotlin.github.io/dataframe/gettingstartedgradle.html + 2023-06-26T12:33:14+00:00 + 0.41 + + + https://kotlin.github.io/dataframe/adddf.html + 2023-06-26T12:33:14+00:00 + 0.41 + + + https://kotlin.github.io/dataframe/cast.html + 2023-06-26T12:33:14+00:00 + 0.41 + + + https://kotlin.github.io/dataframe/stringcolumns.html + 2023-06-26T12:33:14+00:00 + 0.33 + + + https://kotlin.github.io/dataframe/maxby.html + 2023-06-26T12:33:14+00:00 + 0.33 + + + https://kotlin.github.io/dataframe/columnarithmetics.html + 2023-06-26T12:33:14+00:00 + 0.33 + + + https://kotlin.github.io/dataframe/gettingstarted.html + 2023-06-26T12:33:14+00:00 + 0.33 + + + https://kotlin.github.io/dataframe/specialcolumntypes.html + 2023-06-26T12:33:14+00:00 + 0.26 + + + https://kotlin.github.io/dataframe/columnstatistics.html + 2023-06-26T12:33:14+00:00 + 0.26 + + + + \ No newline at end of file From 95dcec587b526710c2205b7e56aa4620a18659c5 Mon Sep 17 00:00:00 2001 From: Jolan Rensen Date: Wed, 26 Jul 2023 14:54:48 +0200 Subject: [PATCH 09/45] different writerside-builder version for dataframes to be rendered --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 9553a3e151..7858c07580 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -22,7 +22,7 @@ env: jobs: build-job: runs-on: ubuntu-latest - container: registry.jetbrains.team/p/writerside/builder/writerside-builder:2.1.1485-p3896 + container: registry.jetbrains.team/p/writerside/builder/writerside-builder:2.1.1481-p3872-df outputs: artifact: ${{ steps.generate-artifact.outputs.artifact }} steps: From 3b86205ed10fad357c971cd897f5c3a78a38cd0a Mon Sep 17 00:00:00 2001 From: Jolan Rensen Date: Mon, 24 Jul 2023 17:45:55 +0200 Subject: [PATCH 10/45] added deprecation messages instructions to RELEASE_CHECK_LIST.md and updated the file with regions and hints to when a feature will be removed --- RELEASE_CHECK_LIST.md | 5 ++++ .../dataframe/util/deprecationMessages.kt | 24 +++++++++++++++---- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/RELEASE_CHECK_LIST.md b/RELEASE_CHECK_LIST.md index 0665b64cb1..2b3c8e1e24 100644 --- a/RELEASE_CHECK_LIST.md +++ b/RELEASE_CHECK_LIST.md @@ -29,3 +29,8 @@ 17. Create Release from the release tag on GitHub 18. Update a KDF version in the [Kotlin Jupyter Descriptor](https://github.com/Kotlin/kotlin-jupyter-libraries/blob/master/dataframe.json). Now the Renovate bot doing this 19. Update DataFrame version in gradle.properties file for next release cycle (i.e. 0.10.0 -> 0.11.0) +20. Update deprecated functions in [deprecationMessages.kt](/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/util/deprecationMessages.kt) + such that + - `Level.WARNING` messages are changed to `Level.ERROR` + - `Level.ERROR` messages and their functions are removed. + - Update regions in the file accordingly. diff --git a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/util/deprecationMessages.kt b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/util/deprecationMessages.kt index aabe39112a..6709c0e4fc 100644 --- a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/util/deprecationMessages.kt +++ b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/util/deprecationMessages.kt @@ -1,13 +1,29 @@ package org.jetbrains.kotlinx.dataframe.util -internal const val DF_READ_DEPRECATION_MESSAGE = "Replaced with `unfold` operation." +/* + * This file contains deprecation messages for the whole core module. + * After each release, all messages should be reviewed and updated. + * Level.WARNING -> Level.ERROR + * Level.ERROR -> Remove + */ +// region WARNING in 0.10.0, ERROR in 0.11.0 + +internal const val DF_READ_DEPRECATION_MESSAGE = "Replaced with `unfold` operation. Removed in 0.11.0." internal const val DF_READ_REPLACE_MESSAGE = "this.unfold(*columns)" -internal const val ITERABLE_COLUMNS_DEPRECATION_MESSAGE = "Replaced with `toColumnSet()` operation." +internal const val ITERABLE_COLUMNS_DEPRECATION_MESSAGE = "Replaced with `toColumnSet()` operation. Removed in 0.11.0." -internal const val DIFF_DEPRECATION_MESSAGE = "Replaced to explicitly indicate nullable return value; added a new non-null overload." +// endregion -internal const val DIFF_REPLACE_MESSAGE = "this.diffOrNull(expression)" +// region WARNING in 0.11.0, ERROR in 0.12.0 +internal const val DIFF_DEPRECATION_MESSAGE = "Replaced to explicitly indicate nullable return value; added a new non-null overload. Will be removed in 0.12.0." +internal const val DIFF_REPLACE_MESSAGE = "this.diffOrNull(expression)" internal const val DIFF_OR_NULL_IMPORT = "org.jetbrains.kotlinx.dataframe.api.diffOrNull" + +// endregion + +// region WARNING in 0.12.0, ERROR in 0.13.0 + +// endregion From e011185c5a443545c05409dbc2dad7b2dff6d14e Mon Sep 17 00:00:00 2001 From: Jolan Rensen Date: Tue, 25 Jul 2023 13:08:44 +0200 Subject: [PATCH 11/45] added update deprecation messages to central file --- .../jetbrains/kotlinx/dataframe/api/update.kt | 13 +++++--- .../dataframe/util/deprecationMessages.kt | 30 ++++++++++++++++--- .../jetbrains/kotlinx/dataframe/api/update.kt | 13 +++++--- .../dataframe/util/deprecationMessages.kt | 6 ++++ 4 files changed, 50 insertions(+), 12 deletions(-) diff --git a/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/update.kt b/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/update.kt index dbed59ac10..cb335c9d2a 100644 --- a/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/update.kt +++ b/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/update.kt @@ -12,6 +12,10 @@ import org.jetbrains.kotlinx.dataframe.impl.api.updateImpl import org.jetbrains.kotlinx.dataframe.impl.api.updateWithValuePerColumnImpl import org.jetbrains.kotlinx.dataframe.impl.headPlusArray import org.jetbrains.kotlinx.dataframe.util.ITERABLE_COLUMNS_DEPRECATION_MESSAGE +import org.jetbrains.kotlinx.dataframe.util.UPDATE_AS_NULLABLE_MESSAGE +import org.jetbrains.kotlinx.dataframe.util.UPDATE_AS_NULLABLE_REPLACE +import org.jetbrains.kotlinx.dataframe.util.UPDATE_WITH_VALUE +import org.jetbrains.kotlinx.dataframe.util.UPDATE_WITH_VALUE_REPLACE import kotlin.reflect.KProperty /** @@ -403,8 +407,9 @@ public fun Update>.asFrame(expression: DataFrameExpressi asFrameImpl(expression) @Deprecated( - "Useless unless in combination with `withValue(null)`, but then users can just use `with { null }`...", - ReplaceWith("this as Update") + UPDATE_AS_NULLABLE_MESSAGE, + ReplaceWith(UPDATE_AS_NULLABLE_REPLACE), + DeprecationLevel.WARNING, ) public fun Update.asNullable(): Update = this as Update @@ -752,7 +757,7 @@ public fun Update.withNull(): DataFrame = with { null } public fun Update.withZero(): DataFrame = updateWithValuePerColumnImpl { 0 as C } /** - * ## With Value + * ## With Value (Deprecated) * Specific version of [with][org.jetbrains.kotlinx.dataframe.api.with] that simply sets the value of each selected row to [value]. * * For example: @@ -763,5 +768,5 @@ public fun Update.withZero(): DataFrame = updateWithValuePerColu * * @param [value] The value to set the selected rows to. In contrast to [with][Update.with], this must be the same exact type. */ -@Deprecated("Use with { value } instead", ReplaceWith("this.with { value }")) +@Deprecated(UPDATE_WITH_VALUE, ReplaceWith(UPDATE_WITH_VALUE_REPLACE), DeprecationLevel.WARNING) public fun Update.withValue(value: C): DataFrame = with { value } diff --git a/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/util/deprecationMessages.kt b/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/util/deprecationMessages.kt index aabe39112a..f3f3016be5 100644 --- a/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/util/deprecationMessages.kt +++ b/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/util/deprecationMessages.kt @@ -1,13 +1,35 @@ package org.jetbrains.kotlinx.dataframe.util -internal const val DF_READ_DEPRECATION_MESSAGE = "Replaced with `unfold` operation." +/* + * This file contains deprecation messages for the whole core module. + * After each release, all messages should be reviewed and updated. + * Level.WARNING -> Level.ERROR + * Level.ERROR -> Remove + */ +// region WARNING in 0.10.0, ERROR in 0.11.0 + +internal const val DF_READ_DEPRECATION_MESSAGE = "Replaced with `unfold` operation. Removed in 0.11.0." internal const val DF_READ_REPLACE_MESSAGE = "this.unfold(*columns)" -internal const val ITERABLE_COLUMNS_DEPRECATION_MESSAGE = "Replaced with `toColumnSet()` operation." +internal const val ITERABLE_COLUMNS_DEPRECATION_MESSAGE = "Replaced with `toColumnSet()` operation. Removed in 0.11.0." -internal const val DIFF_DEPRECATION_MESSAGE = "Replaced to explicitly indicate nullable return value; added a new non-null overload." +// endregion -internal const val DIFF_REPLACE_MESSAGE = "this.diffOrNull(expression)" +// region WARNING in 0.11.0, ERROR in 0.12.0 +internal const val DIFF_DEPRECATION_MESSAGE = "Replaced to explicitly indicate nullable return value; added a new non-null overload. Will be removed in 0.12.0." +internal const val DIFF_REPLACE_MESSAGE = "this.diffOrNull(expression)" internal const val DIFF_OR_NULL_IMPORT = "org.jetbrains.kotlinx.dataframe.api.diffOrNull" + +internal const val UPDATE_AS_NULLABLE_MESSAGE = "This function is useless unless in combination with `withValue(null)`, but then you can just use `with { null }`. Will be removed in 0.12.0." +internal const val UPDATE_AS_NULLABLE_REPLACE = "this as Update" + +internal const val UPDATE_WITH_VALUE = "Replaced in favor of `with { value }`. Will be removed in 0.12.0." +internal const val UPDATE_WITH_VALUE_REPLACE = "this.with { value }" + +// endregion + +// region WARNING in 0.12.0, ERROR in 0.13.0 + +// endregion diff --git a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/update.kt b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/update.kt index 8cddfeaf0a..fa4ed2dfeb 100644 --- a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/update.kt +++ b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/update.kt @@ -12,6 +12,10 @@ import org.jetbrains.kotlinx.dataframe.impl.api.updateImpl import org.jetbrains.kotlinx.dataframe.impl.api.updateWithValuePerColumnImpl import org.jetbrains.kotlinx.dataframe.impl.headPlusArray import org.jetbrains.kotlinx.dataframe.util.ITERABLE_COLUMNS_DEPRECATION_MESSAGE +import org.jetbrains.kotlinx.dataframe.util.UPDATE_AS_NULLABLE_MESSAGE +import org.jetbrains.kotlinx.dataframe.util.UPDATE_AS_NULLABLE_REPLACE +import org.jetbrains.kotlinx.dataframe.util.UPDATE_WITH_VALUE +import org.jetbrains.kotlinx.dataframe.util.UPDATE_WITH_VALUE_REPLACE import kotlin.reflect.KProperty /** @@ -247,8 +251,9 @@ public fun Update>.asFrame(expression: DataFrameExpressi asFrameImpl(expression) @Deprecated( - "Useless unless in combination with `withValue(null)`, but then users can just use `with { null }`...", - ReplaceWith("this as Update") + UPDATE_AS_NULLABLE_MESSAGE, + ReplaceWith(UPDATE_AS_NULLABLE_REPLACE), + DeprecationLevel.WARNING, ) public fun Update.asNullable(): Update = this as Update @@ -445,12 +450,12 @@ public fun Update.withNull(): DataFrame = with { null } public fun Update.withZero(): DataFrame = updateWithValuePerColumnImpl { 0 as C } /** - * ## With Value + * ## With Value (Deprecated) * @include [CommonSpecificWithDoc] * {@arg [CommonSpecificWithDocFirstArg] [value]} * {@arg [CommonSpecificWithDocSecondArg] [withValue][withValue]`(-1)} * * @param [value] The value to set the selected rows to. In contrast to [with][Update.with], this must be the same exact type. */ -@Deprecated("Use with { value } instead", ReplaceWith("this.with { value }")) +@Deprecated(UPDATE_WITH_VALUE, ReplaceWith(UPDATE_WITH_VALUE_REPLACE), DeprecationLevel.WARNING) public fun Update.withValue(value: C): DataFrame = with { value } diff --git a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/util/deprecationMessages.kt b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/util/deprecationMessages.kt index 6709c0e4fc..f3f3016be5 100644 --- a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/util/deprecationMessages.kt +++ b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/util/deprecationMessages.kt @@ -22,6 +22,12 @@ internal const val DIFF_DEPRECATION_MESSAGE = "Replaced to explicitly indicate n internal const val DIFF_REPLACE_MESSAGE = "this.diffOrNull(expression)" internal const val DIFF_OR_NULL_IMPORT = "org.jetbrains.kotlinx.dataframe.api.diffOrNull" +internal const val UPDATE_AS_NULLABLE_MESSAGE = "This function is useless unless in combination with `withValue(null)`, but then you can just use `with { null }`. Will be removed in 0.12.0." +internal const val UPDATE_AS_NULLABLE_REPLACE = "this as Update" + +internal const val UPDATE_WITH_VALUE = "Replaced in favor of `with { value }`. Will be removed in 0.12.0." +internal const val UPDATE_WITH_VALUE_REPLACE = "this.with { value }" + // endregion // region WARNING in 0.12.0, ERROR in 0.13.0 From 3d42730f7105ccdf577bc0c6a224ed38e28b905c Mon Sep 17 00:00:00 2001 From: Jolan Rensen Date: Tue, 25 Jul 2023 14:59:47 +0200 Subject: [PATCH 12/45] made removed in x.x.x general too --- .../dataframe/util/deprecationMessages.kt | 16 +++++++++++----- .../dataframe/util/deprecationMessages.kt | 16 +++++++++++----- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/util/deprecationMessages.kt b/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/util/deprecationMessages.kt index f3f3016be5..3acb2d2d67 100644 --- a/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/util/deprecationMessages.kt +++ b/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/util/deprecationMessages.kt @@ -9,27 +9,33 @@ package org.jetbrains.kotlinx.dataframe.util // region WARNING in 0.10.0, ERROR in 0.11.0 -internal const val DF_READ_DEPRECATION_MESSAGE = "Replaced with `unfold` operation. Removed in 0.11.0." +private const val message_0_11_0 = "Was removed in 0.11.0." + +internal const val DF_READ_DEPRECATION_MESSAGE = "Replaced with `unfold` operation. $message_0_11_0" internal const val DF_READ_REPLACE_MESSAGE = "this.unfold(*columns)" -internal const val ITERABLE_COLUMNS_DEPRECATION_MESSAGE = "Replaced with `toColumnSet()` operation. Removed in 0.11.0." +internal const val ITERABLE_COLUMNS_DEPRECATION_MESSAGE = "Replaced with `toColumnSet()` operation. $message_0_11_0" // endregion // region WARNING in 0.11.0, ERROR in 0.12.0 -internal const val DIFF_DEPRECATION_MESSAGE = "Replaced to explicitly indicate nullable return value; added a new non-null overload. Will be removed in 0.12.0." +private const val message_0_12_0 = "Will be removed in 0.12.0." + +internal const val DIFF_DEPRECATION_MESSAGE = "Replaced to explicitly indicate nullable return value; added a new non-null overload. $message_0_12_0" internal const val DIFF_REPLACE_MESSAGE = "this.diffOrNull(expression)" internal const val DIFF_OR_NULL_IMPORT = "org.jetbrains.kotlinx.dataframe.api.diffOrNull" -internal const val UPDATE_AS_NULLABLE_MESSAGE = "This function is useless unless in combination with `withValue(null)`, but then you can just use `with { null }`. Will be removed in 0.12.0." +internal const val UPDATE_AS_NULLABLE_MESSAGE = "This function is useless unless in combination with `withValue(null)`, but then you can just use `with { null }`. $message_0_12_0" internal const val UPDATE_AS_NULLABLE_REPLACE = "this as Update" -internal const val UPDATE_WITH_VALUE = "Replaced in favor of `with { value }`. Will be removed in 0.12.0." +internal const val UPDATE_WITH_VALUE = "Replaced in favor of `with { value }`. $message_0_12_0" internal const val UPDATE_WITH_VALUE_REPLACE = "this.with { value }" // endregion // region WARNING in 0.12.0, ERROR in 0.13.0 +private const val message_0_13_0 = "Will be removed in 0.13.0." + // endregion diff --git a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/util/deprecationMessages.kt b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/util/deprecationMessages.kt index f3f3016be5..3acb2d2d67 100644 --- a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/util/deprecationMessages.kt +++ b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/util/deprecationMessages.kt @@ -9,27 +9,33 @@ package org.jetbrains.kotlinx.dataframe.util // region WARNING in 0.10.0, ERROR in 0.11.0 -internal const val DF_READ_DEPRECATION_MESSAGE = "Replaced with `unfold` operation. Removed in 0.11.0." +private const val message_0_11_0 = "Was removed in 0.11.0." + +internal const val DF_READ_DEPRECATION_MESSAGE = "Replaced with `unfold` operation. $message_0_11_0" internal const val DF_READ_REPLACE_MESSAGE = "this.unfold(*columns)" -internal const val ITERABLE_COLUMNS_DEPRECATION_MESSAGE = "Replaced with `toColumnSet()` operation. Removed in 0.11.0." +internal const val ITERABLE_COLUMNS_DEPRECATION_MESSAGE = "Replaced with `toColumnSet()` operation. $message_0_11_0" // endregion // region WARNING in 0.11.0, ERROR in 0.12.0 -internal const val DIFF_DEPRECATION_MESSAGE = "Replaced to explicitly indicate nullable return value; added a new non-null overload. Will be removed in 0.12.0." +private const val message_0_12_0 = "Will be removed in 0.12.0." + +internal const val DIFF_DEPRECATION_MESSAGE = "Replaced to explicitly indicate nullable return value; added a new non-null overload. $message_0_12_0" internal const val DIFF_REPLACE_MESSAGE = "this.diffOrNull(expression)" internal const val DIFF_OR_NULL_IMPORT = "org.jetbrains.kotlinx.dataframe.api.diffOrNull" -internal const val UPDATE_AS_NULLABLE_MESSAGE = "This function is useless unless in combination with `withValue(null)`, but then you can just use `with { null }`. Will be removed in 0.12.0." +internal const val UPDATE_AS_NULLABLE_MESSAGE = "This function is useless unless in combination with `withValue(null)`, but then you can just use `with { null }`. $message_0_12_0" internal const val UPDATE_AS_NULLABLE_REPLACE = "this as Update" -internal const val UPDATE_WITH_VALUE = "Replaced in favor of `with { value }`. Will be removed in 0.12.0." +internal const val UPDATE_WITH_VALUE = "Replaced in favor of `with { value }`. $message_0_12_0" internal const val UPDATE_WITH_VALUE_REPLACE = "this.with { value }" // endregion // region WARNING in 0.12.0, ERROR in 0.13.0 +private const val message_0_13_0 = "Will be removed in 0.13.0." + // endregion From 9b60e960ae2e9082e99a9e939d34eb8c3403c585 Mon Sep 17 00:00:00 2001 From: Nikita Klimenko Date: Thu, 27 Jul 2023 15:25:01 +0300 Subject: [PATCH 13/45] make footer optional --- .../jetbrains/kotlinx/dataframe/io/html.kt | 28 +++++++++++-------- .../jetbrains/kotlinx/dataframe/io/html.kt | 28 +++++++++++-------- 2 files changed, 34 insertions(+), 22 deletions(-) diff --git a/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/io/html.kt b/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/io/html.kt index 229c13d0dc..cfbc6a73d0 100644 --- a/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/io/html.kt +++ b/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/io/html.kt @@ -183,7 +183,7 @@ public fun DataFrame.html(): String = toStandaloneHTML().toString() public fun DataFrame.toStandaloneHTML( configuration: DisplayConfiguration = DisplayConfiguration.DEFAULT, cellRenderer: CellRenderer = org.jetbrains.kotlinx.dataframe.jupyter.DefaultCellRenderer, - getFooter: (DataFrame) -> String = { "DataFrame [${it.size}]" }, + getFooter: (DataFrame) -> String? = { "DataFrame [${it.size}]" }, ): DataFrameHtmlData = toHTML(configuration, cellRenderer, getFooter).withTableDefinitions() /** @@ -192,25 +192,31 @@ public fun DataFrame.toStandaloneHTML( public fun DataFrame.toHTML( configuration: DisplayConfiguration = DisplayConfiguration.DEFAULT, cellRenderer: CellRenderer = org.jetbrains.kotlinx.dataframe.jupyter.DefaultCellRenderer, - getFooter: (DataFrame) -> String = { "DataFrame [${it.size}]" }, + getFooter: (DataFrame) -> String? = { "DataFrame [${it.size}]" }, ): DataFrameHtmlData { val limit = configuration.rowsLimit ?: Int.MAX_VALUE val footer = getFooter(this) - val bodyFooter = buildString { - val openPTag = "

" - if (limit < nrow) { + val bodyFooter = footer?.let { + buildString { + val openPTag = "

" + if (limit < nrow) { + append(openPTag) + append("... showing only top $limit of $nrow rows

") + } append(openPTag) - append("... showing only top $limit of $nrow rows

") + append(footer) + append("

") } - append(openPTag) - append(footer) - append("

") } - val tableHtml = toHtmlData(configuration, cellRenderer) + var tableHtml = toHtmlData(configuration, cellRenderer) + + if (bodyFooter != null) { + tableHtml += DataFrameHtmlData("", bodyFooter, "") + } - return tableHtml + DataFrameHtmlData("", bodyFooter, "") + return tableHtml } /** diff --git a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/io/html.kt b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/io/html.kt index 229c13d0dc..cfbc6a73d0 100644 --- a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/io/html.kt +++ b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/io/html.kt @@ -183,7 +183,7 @@ public fun DataFrame.html(): String = toStandaloneHTML().toString() public fun DataFrame.toStandaloneHTML( configuration: DisplayConfiguration = DisplayConfiguration.DEFAULT, cellRenderer: CellRenderer = org.jetbrains.kotlinx.dataframe.jupyter.DefaultCellRenderer, - getFooter: (DataFrame) -> String = { "DataFrame [${it.size}]" }, + getFooter: (DataFrame) -> String? = { "DataFrame [${it.size}]" }, ): DataFrameHtmlData = toHTML(configuration, cellRenderer, getFooter).withTableDefinitions() /** @@ -192,25 +192,31 @@ public fun DataFrame.toStandaloneHTML( public fun DataFrame.toHTML( configuration: DisplayConfiguration = DisplayConfiguration.DEFAULT, cellRenderer: CellRenderer = org.jetbrains.kotlinx.dataframe.jupyter.DefaultCellRenderer, - getFooter: (DataFrame) -> String = { "DataFrame [${it.size}]" }, + getFooter: (DataFrame) -> String? = { "DataFrame [${it.size}]" }, ): DataFrameHtmlData { val limit = configuration.rowsLimit ?: Int.MAX_VALUE val footer = getFooter(this) - val bodyFooter = buildString { - val openPTag = "

" - if (limit < nrow) { + val bodyFooter = footer?.let { + buildString { + val openPTag = "

" + if (limit < nrow) { + append(openPTag) + append("... showing only top $limit of $nrow rows

") + } append(openPTag) - append("... showing only top $limit of $nrow rows

") + append(footer) + append("

") } - append(openPTag) - append(footer) - append("

") } - val tableHtml = toHtmlData(configuration, cellRenderer) + var tableHtml = toHtmlData(configuration, cellRenderer) + + if (bodyFooter != null) { + tableHtml += DataFrameHtmlData("", bodyFooter, "") + } - return tableHtml + DataFrameHtmlData("", bodyFooter, "") + return tableHtml } /** From 5d181cf9bd8af0c30dd2793a2b44c21a3cf56ea2 Mon Sep 17 00:00:00 2001 From: Nikita Klimenko Date: Thu, 27 Jul 2023 15:26:16 +0300 Subject: [PATCH 14/45] optimize allocations according to inspections --- .../org/jetbrains/kotlinx/dataframe/impl/api/join.kt | 12 ++++++------ .../org/jetbrains/kotlinx/dataframe/impl/api/join.kt | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/api/join.kt b/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/api/join.kt index daad1cde21..37a63906c4 100644 --- a/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/api/join.kt +++ b/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/api/join.kt @@ -29,12 +29,12 @@ import org.jetbrains.kotlinx.dataframe.type import kotlin.reflect.full.withNullability internal fun defaultJoinColumns(left: DataFrame, right: DataFrame): JoinColumnsSelector = - { left.columnNames().intersect(right.columnNames()).map { it.toColumnAccessor() }.let { ColumnsList(it) } } + { left.columnNames().intersect(right.columnNames().toSet()).map { it.toColumnAccessor() }.let { ColumnsList(it) } } internal fun defaultJoinColumns(dataFrames: Iterable>): JoinColumnsSelector = { dataFrames.map { it.columnNames() }.fold, Set?>(null) { set, names -> - set?.intersect(names) ?: names.toSet() + set?.intersect(names.toSet()) ?: names.toSet() }.orEmpty().map { it.toColumnAccessor() }.let { ColumnsList(it) } } @@ -114,7 +114,7 @@ internal fun DataFrame.joinImpl( // group row indices by key from right data frame val groupedRight = when (joinType) { - JoinType.Exclude -> rightJoinKeyToIndex.map { it.first to emptyList() }.toMap() + JoinType.Exclude -> rightJoinKeyToIndex.associate { it.first to emptyList() } else -> rightJoinKeyToIndex.groupBy({ it.first }) { it.second } } @@ -129,7 +129,7 @@ internal fun DataFrame.joinImpl( } // for every row index in right data frame store a flag indicating whether this row was matched by some row in left data frame - val rightMatched = Array(other.nrow) { false } + val rightMatched = BooleanArray(other.nrow) { false } // number of rows in right data frame that were not matched by any row in left data frame. Used for correct allocation of an output array var rightUnmatchedCount = other.nrow @@ -162,8 +162,8 @@ internal fun DataFrame.joinImpl( val newRightColumnsCount = newRightColumns.size val outputColumnsCount = leftColumnsCount + newRightColumnsCount - val outputData = Array>(outputColumnsCount) { arrayOfNulls(outputRowsCount) } - val hasNulls = Array(outputColumnsCount) { false } + val outputData = List>(outputColumnsCount) { arrayOfNulls(outputRowsCount) } + val hasNulls = BooleanArray(outputColumnsCount) { false } var row = 0 diff --git a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/api/join.kt b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/api/join.kt index daad1cde21..37a63906c4 100644 --- a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/api/join.kt +++ b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/api/join.kt @@ -29,12 +29,12 @@ import org.jetbrains.kotlinx.dataframe.type import kotlin.reflect.full.withNullability internal fun defaultJoinColumns(left: DataFrame, right: DataFrame): JoinColumnsSelector = - { left.columnNames().intersect(right.columnNames()).map { it.toColumnAccessor() }.let { ColumnsList(it) } } + { left.columnNames().intersect(right.columnNames().toSet()).map { it.toColumnAccessor() }.let { ColumnsList(it) } } internal fun defaultJoinColumns(dataFrames: Iterable>): JoinColumnsSelector = { dataFrames.map { it.columnNames() }.fold, Set?>(null) { set, names -> - set?.intersect(names) ?: names.toSet() + set?.intersect(names.toSet()) ?: names.toSet() }.orEmpty().map { it.toColumnAccessor() }.let { ColumnsList(it) } } @@ -114,7 +114,7 @@ internal fun DataFrame.joinImpl( // group row indices by key from right data frame val groupedRight = when (joinType) { - JoinType.Exclude -> rightJoinKeyToIndex.map { it.first to emptyList() }.toMap() + JoinType.Exclude -> rightJoinKeyToIndex.associate { it.first to emptyList() } else -> rightJoinKeyToIndex.groupBy({ it.first }) { it.second } } @@ -129,7 +129,7 @@ internal fun DataFrame.joinImpl( } // for every row index in right data frame store a flag indicating whether this row was matched by some row in left data frame - val rightMatched = Array(other.nrow) { false } + val rightMatched = BooleanArray(other.nrow) { false } // number of rows in right data frame that were not matched by any row in left data frame. Used for correct allocation of an output array var rightUnmatchedCount = other.nrow @@ -162,8 +162,8 @@ internal fun DataFrame.joinImpl( val newRightColumnsCount = newRightColumns.size val outputColumnsCount = leftColumnsCount + newRightColumnsCount - val outputData = Array>(outputColumnsCount) { arrayOfNulls(outputRowsCount) } - val hasNulls = Array(outputColumnsCount) { false } + val outputData = List>(outputColumnsCount) { arrayOfNulls(outputRowsCount) } + val hasNulls = BooleanArray(outputColumnsCount) { false } var row = 0 From 3f824f6eec10ebe063662d44e2e0d1111ebd5037 Mon Sep 17 00:00:00 2001 From: Nikita Klimenko Date: Mon, 31 Jul 2023 22:18:37 +0300 Subject: [PATCH 15/45] add missing DataRow operations --- docs/StardustDocs/topics/DataRow.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/StardustDocs/topics/DataRow.md b/docs/StardustDocs/topics/DataRow.md index e7400a4fda..8a120c4a23 100644 --- a/docs/StardustDocs/topics/DataRow.md +++ b/docs/StardustDocs/topics/DataRow.md @@ -11,6 +11,7 @@ * `prev(): DataRow?` — previous row (`null` for the first row) * `next(): DataRow?` — next row (`null` for the last row) * `diff(T) { rowExpression }: T / diffOrNull { rowExpression }: T?` — difference between the results of a [row expression](DataRow.md#row-expressions) calculated for current and previous rows +* `explode(columns): DataFrame` — spread lists and [`DataFrames`](DataFrame.md) vertically into new rows * `values(): List` — list of all cell values from the current row * `valuesOf(): List` — list of values of the given type * `columnsCount(): Int` — number of columns @@ -23,7 +24,12 @@ * `getRow(Int): DataRow` — row from [`DataFrame`](DataFrame.md) by row index * `getRows(Iterable): DataFrame` — dataframe with subset of rows selected by absolute row index. * `relative(Iterable): DataFrame` — dataframe with subset of rows selected by relative row index: `relative(-1..1)` will return previous, current and next row. Requested indices will be coerced to the valid range and invalid indices will be skipped +* `getValue(columnName)` — cell value of type `T` by this row and given `columnName` +* `getValueOrNull(columnName)` — cell value of type `T?` by this row and given `columnName` or `null` if there's no such column * `get(column): T` — cell value by this row and given `column` +* `String.invoke(): T` — cell value of type `T` by this row and given `this` column name +* `ColumnPath.invoke(): T` — cell value of type `T` by this row and given `this` column path +* `ColumnReference.invoke(): T` — cell value of type `T` by this row and given `this` column * `df()` — [`DataFrame`](DataFrame.md) that current row belongs to From 604da9e576c854e7f6f91113aed2759e92453338 Mon Sep 17 00:00:00 2001 From: Nikita Klimenko Date: Wed, 2 Aug 2023 13:12:47 +0300 Subject: [PATCH 16/45] update KSP to 1.9.0-1.0.12 --- gradle/libs.versions.toml | 2 +- plugins/symbol-processor/build.gradle | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 4e948a9573..93d69fc378 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,5 +1,5 @@ [versions] -ksp = "1.8.20-1.0.11" +ksp = "1.9.0-1.0.12" kotlinJupyter = "0.11.0-358" ktlint = "3.4.5" kotlin = "1.8.20" diff --git a/plugins/symbol-processor/build.gradle b/plugins/symbol-processor/build.gradle index 02bd072480..78e2a73e7a 100644 --- a/plugins/symbol-processor/build.gradle +++ b/plugins/symbol-processor/build.gradle @@ -20,8 +20,8 @@ dependencies { implementation(libs.ksp.api) implementation(libs.kotlin.reflect) testImplementation("org.jetbrains.kotlin:kotlin-test") - testImplementation("com.github.tschuchortdev:kotlin-compile-testing:1.4.9") - testImplementation("com.github.tschuchortdev:kotlin-compile-testing-ksp:1.4.9") + testImplementation("com.github.tschuchortdev:kotlin-compile-testing:1.5.0") + testImplementation("com.github.tschuchortdev:kotlin-compile-testing-ksp:1.5.0") testImplementation("io.ktor:ktor-server-netty:1.6.7") testImplementation("io.kotest:kotest-assertions-core:4.6.0") } From 6328a35ad8ece28b9b6bd67c8490700fdc04ca4e Mon Sep 17 00:00:00 2001 From: Nikita Klimenko Date: Wed, 2 Aug 2023 13:55:29 +0300 Subject: [PATCH 17/45] add Binder badge --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index e53d03e95b..8ea21e159b 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,7 @@ [![Kotlin](https://img.shields.io/badge/kotlin-1.8.20-blue.svg?logo=kotlin)](http://kotlinlang.org) [![Maven Central](https://img.shields.io/maven-central/v/org.jetbrains.kotlinx/dataframe?color=blue&label=Maven%20Central)](https://search.maven.org/artifact/org.jetbrains.kotlinx/dataframe) [![GitHub License](https://img.shields.io/badge/license-Apache%20License%202.0-blue.svg?style=flat)](http://www.apache.org/licenses/LICENSE-2.0) +[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/Kotlin/dataframe/HEAD) Kotlin Dataframe aims to reconcile Kotlin's static typing with the dynamic nature of data by utilizing both the full power of the Kotlin language and the opportunities provided by intermittent code execution in Jupyter notebooks and REPL. From 952e15ae66e2c1580d358f08364b100ac1ae2f43 Mon Sep 17 00:00:00 2001 From: Nikita Klimenko Date: Wed, 2 Aug 2023 14:03:44 +0300 Subject: [PATCH 18/45] update Kotlin to 1.9.0 --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 93d69fc378..716f20151b 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -2,7 +2,7 @@ ksp = "1.9.0-1.0.12" kotlinJupyter = "0.11.0-358" ktlint = "3.4.5" -kotlin = "1.8.20" +kotlin = "1.9.0" dokka = "1.8.10" libsPublisher = "0.0.60-dev-30" # "Bootstrap" version of the dataframe, used in the build itself to generate @DataSchema APIs, From cb3c129457e2e3c7094ba06b7ddf5f5e63fa5e98 Mon Sep 17 00:00:00 2001 From: Jolan Rensen Date: Thu, 3 Aug 2023 12:12:00 +0200 Subject: [PATCH 19/45] small refactoring of tests, updating from master --- .../test/kotlin/org/jetbrains/kotlinx/dataframe/api/sort.kt | 6 +++--- .../test/kotlin/org/jetbrains/kotlinx/dataframe/api/sort.kt | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/core/generated-sources/src/test/kotlin/org/jetbrains/kotlinx/dataframe/api/sort.kt b/core/generated-sources/src/test/kotlin/org/jetbrains/kotlinx/dataframe/api/sort.kt index a04dc3f8fd..8ac9ebc5f0 100644 --- a/core/generated-sources/src/test/kotlin/org/jetbrains/kotlinx/dataframe/api/sort.kt +++ b/core/generated-sources/src/test/kotlin/org/jetbrains/kotlinx/dataframe/api/sort.kt @@ -17,7 +17,7 @@ class SortDataColumn { col.sortWith { a, b -> b - a } shouldBe descSortedCol col.sortWith(Int::compareTo) shouldBe sortedCol - col.sortWith(Comparator(Int::compareTo)) shouldBe sortedCol + col.sortWith(compareBy { it }) shouldBe sortedCol } @Test @@ -40,7 +40,7 @@ class SortDataColumn { ) col.sortWith { df1, df2 -> df1.nrow - df2.nrow } shouldBe sortedCol - col.sortWith(Comparator { df1, df2 -> df1.nrow - df2.nrow }) shouldBe sortedCol + col.sortWith(compareBy { it.nrow }) shouldBe sortedCol } @Test @@ -65,6 +65,6 @@ class SortDataColumn { ) col.sortWith { df1, df2 -> df1[a] - df2[a] } shouldBe sortedCol - col.sortWith(Comparator { df1, df2 -> df1[a] - df2[a] }) shouldBe sortedCol + col.sortWith(compareBy { it[a] }) shouldBe sortedCol } } diff --git a/core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/api/sort.kt b/core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/api/sort.kt index a04dc3f8fd..8ac9ebc5f0 100644 --- a/core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/api/sort.kt +++ b/core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/api/sort.kt @@ -17,7 +17,7 @@ class SortDataColumn { col.sortWith { a, b -> b - a } shouldBe descSortedCol col.sortWith(Int::compareTo) shouldBe sortedCol - col.sortWith(Comparator(Int::compareTo)) shouldBe sortedCol + col.sortWith(compareBy { it }) shouldBe sortedCol } @Test @@ -40,7 +40,7 @@ class SortDataColumn { ) col.sortWith { df1, df2 -> df1.nrow - df2.nrow } shouldBe sortedCol - col.sortWith(Comparator { df1, df2 -> df1.nrow - df2.nrow }) shouldBe sortedCol + col.sortWith(compareBy { it.nrow }) shouldBe sortedCol } @Test @@ -65,6 +65,6 @@ class SortDataColumn { ) col.sortWith { df1, df2 -> df1[a] - df2[a] } shouldBe sortedCol - col.sortWith(Comparator { df1, df2 -> df1[a] - df2[a] }) shouldBe sortedCol + col.sortWith(compareBy { it[a] }) shouldBe sortedCol } } From 478379c26ebacb34d706adfa76b042579b0e63d2 Mon Sep 17 00:00:00 2001 From: Nikita Klimenko Date: Thu, 3 Aug 2023 21:00:14 +0300 Subject: [PATCH 20/45] update dataframe version --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 716f20151b..e16e645413 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -7,7 +7,7 @@ dokka = "1.8.10" libsPublisher = "0.0.60-dev-30" # "Bootstrap" version of the dataframe, used in the build itself to generate @DataSchema APIs, # dogfood Gradle / KSP plugins in tests and idea-examples modules -dataframe = "0.11.0" +dataframe = "0.12.0-dev-2255" korro = "0.1.5" kover = "0.6.0-Beta" From ff7f1d1766ab1f3c05769e2fdce54ac6aea64ff5 Mon Sep 17 00:00:00 2001 From: Nikita Klimenko Date: Fri, 4 Aug 2023 15:34:39 +0300 Subject: [PATCH 21/45] Configure integrationTest using new notation instead of the deprecated one --- plugins/dataframe-gradle-plugin/build.gradle.kts | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/plugins/dataframe-gradle-plugin/build.gradle.kts b/plugins/dataframe-gradle-plugin/build.gradle.kts index def1a39686..ba81c9e8e0 100644 --- a/plugins/dataframe-gradle-plugin/build.gradle.kts +++ b/plugins/dataframe-gradle-plugin/build.gradle.kts @@ -1,3 +1,5 @@ +import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet + plugins { `kotlin-dsl` `java-gradle-plugin` @@ -104,13 +106,13 @@ tasks.withType().all { } sourceSets { + val main by getting + val test by getting + val testRuntimeClasspath by configurations create("integrationTest") { - withConvention(org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet::class) { - kotlin.srcDir("src/integrationTest/kotlin") - resources.srcDir("src/integrationTest/resources") - compileClasspath += sourceSets["main"].output + sourceSets["test"].output + configurations["testRuntimeClasspath"] - runtimeClasspath += output + compileClasspath + sourceSets["test"].runtimeClasspath - } + kotlin.srcDir("src/integrationTest/kotlin") + compileClasspath += main.output + test.output + testRuntimeClasspath + runtimeClasspath += output + compileClasspath + test.runtimeClasspath } } From 6734326cac4b92eeb673972209b7703e2e7237d9 Mon Sep 17 00:00:00 2001 From: Nikita Klimenko Date: Fri, 4 Aug 2023 16:16:04 +0300 Subject: [PATCH 22/45] update gradle wrapper this version is needed to fix bug with unresolved references --- gradle/wrapper/gradle-wrapper.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index da1db5f04e..b982b3c6bb 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-rc-2-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists From f230635673d1573adceddf3bf0bdce1be366297b Mon Sep 17 00:00:00 2001 From: Nikita Klimenko Date: Mon, 7 Aug 2023 15:37:56 +0300 Subject: [PATCH 23/45] release 0.11.1 --- README.md | 17 +++++++++-------- docs/StardustDocs/v.list | 2 +- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 8ea21e159b..c47fef495b 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ Explore [**documentation**](https://kotlin.github.io/dataframe/overview.html) fo plugins { // Optional Gradle plugin for enhanced type safety and schema generation // https://kotlin.github.io/dataframe/gradle.html - id 'org.jetbrains.kotlinx.dataframe' version '0.11.0' + id 'org.jetbrains.kotlinx.dataframe' version '0.11.1' } repositories { @@ -39,7 +39,7 @@ repositories { } dependencies { - implementation 'org.jetbrains.kotlinx:dataframe:0.11.0' + implementation 'org.jetbrains.kotlinx:dataframe:0.11.1' } ``` @@ -49,7 +49,7 @@ dependencies { plugins { // Optional Gradle plugin for enhanced type safety and schema generation // https://kotlin.github.io/dataframe/gradle.html - id("org.jetbrains.kotlinx.dataframe") version "0.11.0" + id("org.jetbrains.kotlinx.dataframe") version "0.11.1" } repositories { @@ -57,7 +57,7 @@ repositories { } dependencies { - implementation("org.jetbrains.kotlinx:dataframe:0.11.0") + implementation("org.jetbrains.kotlinx:dataframe:0.11.1") } ``` @@ -68,11 +68,11 @@ dependencies { plugins { // Optional Gradle plugin for enhanced type safety and schema generation // https://kotlin.github.io/dataframe/gradle.html - id 'org.jetbrains.kotlinx.dataframe' version '0.11.0' + id 'org.jetbrains.kotlinx.dataframe' version '0.11.1' } dependencies { - implementation 'org.jetbrains.kotlinx:dataframe:0.11.0' + implementation 'org.jetbrains.kotlinx:dataframe:0.11.1' } android { @@ -116,11 +116,11 @@ tasks.withType(KotlinCompile).configureEach { plugins { // Optional Gradle plugin for enhanced type safety and schema generation // https://kotlin.github.io/dataframe/gradle.html - id("org.jetbrains.kotlinx.dataframe") version "0.11.0" + id("org.jetbrains.kotlinx.dataframe") version "0.11.1" } dependencies { - implementation("org.jetbrains.kotlinx:dataframe:0.11.0") + implementation("org.jetbrains.kotlinx:dataframe:0.11.1") } android { @@ -190,6 +190,7 @@ This table shows the mapping between main library component versions and minimum | 0.10.0 | 8 | 1.8.20 | 0.11.0-358 | 3.0.0 | 11.0.0 | | 0.10.1 | 8 | 1.8.20 | 0.11.0-358 | 3.0.0 | 11.0.0 | | 0.11.0 | 8 | 1.8.20 | 0.11.0-358 | 3.0.0 | 11.0.0 | +| 0.11.1 | 8 | 1.8.20 | 0.11.0-358 | 3.0.0 | 11.0.0 | ## Usage example **Create:** diff --git a/docs/StardustDocs/v.list b/docs/StardustDocs/v.list index 7e6ac2ad4a..245c641eba 100644 --- a/docs/StardustDocs/v.list +++ b/docs/StardustDocs/v.list @@ -1,5 +1,5 @@ - + From 94fb90868867266ea5d6503b3627ef7bf29417bc Mon Sep 17 00:00:00 2001 From: Nikita Klimenko Date: Mon, 31 Jul 2023 22:21:57 +0300 Subject: [PATCH 24/45] ensure all join overloads work as join with respective supplied JoinType --- .../jetbrains/kotlinx/dataframe/api/join.kt | 11 +++++- .../dataframe/testSets/person/BaseJoinTest.kt | 26 +++++++++++++ .../dataframe/testSets/person/JoinTests.kt | 39 +++++++------------ .../jetbrains/kotlinx/dataframe/api/join.kt | 11 +++++- .../dataframe/testSets/person/BaseJoinTest.kt | 26 +++++++++++++ .../dataframe/testSets/person/JoinTests.kt | 39 +++++++------------ docs/StardustDocs/topics/join.md | 1 + 7 files changed, 99 insertions(+), 54 deletions(-) create mode 100644 core/generated-sources/src/test/kotlin/org/jetbrains/kotlinx/dataframe/testSets/person/BaseJoinTest.kt create mode 100644 core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/testSets/person/BaseJoinTest.kt diff --git a/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/join.kt b/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/join.kt index 6fd14236b4..c985766b28 100644 --- a/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/join.kt +++ b/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/join.kt @@ -10,7 +10,9 @@ public fun DataFrame.join( other: DataFrame, type: JoinType = JoinType.Inner, selector: JoinColumnsSelector? = null -): DataFrame = joinImpl(other, type, true, selector) +): DataFrame { + return joinImpl(other, type, addNewColumns = type.addNewColumns, selector) +} public fun DataFrame.join( other: DataFrame, @@ -116,10 +118,17 @@ public enum class JoinType { Left, // all data from left data frame, nulls for mismatches in right data frame Right, // all data from right data frame, nulls for mismatches in left data frame Inner, // only matched data from right and left data frame + Filter, // only matched data from left data frame Full, // all data from left and from right data frame, nulls for any mismatches Exclude // mismatched rows from left data frame } +internal val JoinType.addNewColumns: Boolean + get() = when (this) { + JoinType.Filter, JoinType.Exclude -> false + JoinType.Left, JoinType.Right, JoinType.Inner, JoinType.Full -> true + } + public val JoinType.allowLeftNulls: Boolean get() = this == JoinType.Right || this == JoinType.Full public val JoinType.allowRightNulls: Boolean get() = this == JoinType.Left || this == JoinType.Full || this == JoinType.Exclude diff --git a/core/generated-sources/src/test/kotlin/org/jetbrains/kotlinx/dataframe/testSets/person/BaseJoinTest.kt b/core/generated-sources/src/test/kotlin/org/jetbrains/kotlinx/dataframe/testSets/person/BaseJoinTest.kt new file mode 100644 index 0000000000..8e0f2e790c --- /dev/null +++ b/core/generated-sources/src/test/kotlin/org/jetbrains/kotlinx/dataframe/testSets/person/BaseJoinTest.kt @@ -0,0 +1,26 @@ +package org.jetbrains.kotlinx.dataframe.testSets.person + +import org.jetbrains.kotlinx.dataframe.DataFrame +import org.jetbrains.kotlinx.dataframe.annotations.DataSchema +import org.jetbrains.kotlinx.dataframe.api.cast +import org.jetbrains.kotlinx.dataframe.api.dataFrameOf + +open class BaseJoinTest : BaseTest() { + val df2 = dataFrameOf("name", "origin", "grade", "age")( + "Alice", "London", 3, "young", + "Alice", "London", 5, "old", + "Bob", "Tokyo", 4, "young", + "Bob", "Paris", 5, "old", + "Charlie", "Moscow", 1, "young", + "Charlie", "Moscow", 2, "old", + "Bob", "Paris", 4, null + ) + val typed2: DataFrame = df2.cast() + + @DataSchema + interface Person2 { + val name: String + val origin: String? + val grade: Int + } +} diff --git a/core/generated-sources/src/test/kotlin/org/jetbrains/kotlinx/dataframe/testSets/person/JoinTests.kt b/core/generated-sources/src/test/kotlin/org/jetbrains/kotlinx/dataframe/testSets/person/JoinTests.kt index 47fa300d4c..68962157d8 100644 --- a/core/generated-sources/src/test/kotlin/org/jetbrains/kotlinx/dataframe/testSets/person/JoinTests.kt +++ b/core/generated-sources/src/test/kotlin/org/jetbrains/kotlinx/dataframe/testSets/person/JoinTests.kt @@ -1,49 +1,26 @@ package org.jetbrains.kotlinx.dataframe.testSets.person import io.kotest.matchers.shouldBe -import org.jetbrains.kotlinx.dataframe.DataFrame -import org.jetbrains.kotlinx.dataframe.annotations.DataSchema +import org.jetbrains.kotlinx.dataframe.api.JoinType import org.jetbrains.kotlinx.dataframe.api.addId import org.jetbrains.kotlinx.dataframe.api.all import org.jetbrains.kotlinx.dataframe.api.append -import org.jetbrains.kotlinx.dataframe.api.cast import org.jetbrains.kotlinx.dataframe.api.column import org.jetbrains.kotlinx.dataframe.api.count -import org.jetbrains.kotlinx.dataframe.api.dataFrameOf import org.jetbrains.kotlinx.dataframe.api.distinct import org.jetbrains.kotlinx.dataframe.api.excludeJoin import org.jetbrains.kotlinx.dataframe.api.filter import org.jetbrains.kotlinx.dataframe.api.filterJoin import org.jetbrains.kotlinx.dataframe.api.fullJoin import org.jetbrains.kotlinx.dataframe.api.innerJoin +import org.jetbrains.kotlinx.dataframe.api.join import org.jetbrains.kotlinx.dataframe.api.leftJoin import org.jetbrains.kotlinx.dataframe.api.remove import org.jetbrains.kotlinx.dataframe.api.rightJoin import org.jetbrains.kotlinx.dataframe.api.select import org.junit.Test -class JoinTests : BaseTest() { - - val df2 = dataFrameOf("name", "origin", "grade", "age")( - "Alice", "London", 3, "young", - "Alice", "London", 5, "old", - "Bob", "Tokyo", 4, "young", - "Bob", "Paris", 5, "old", - "Charlie", "Moscow", 1, "young", - "Charlie", "Moscow", 2, "old", - "Bob", "Paris", 4, null - ) - -// Generated Code - - @DataSchema - interface Person2 { - val name: String - val origin: String? - val grade: Int - } - - val typed2: DataFrame = df2.cast() +class JoinTests : BaseJoinTest() { @Test fun `inner join`() { @@ -118,4 +95,14 @@ class JoinTests : BaseTest() { res shouldBe expected } + + @Test + fun `test overloads contract`() { + typed.innerJoin(typed2) { name and it.city.match(right.origin) } shouldBe typed.join(typed2, JoinType.Inner) { name and it.city.match(right.origin) } + typed.leftJoin(typed2) { name and it.city.match(right.origin) } shouldBe typed.join(typed2, JoinType.Left) { name and it.city.match(right.origin) } + typed.rightJoin(typed2) { name and it.city.match(right.origin) } shouldBe typed.join(typed2, JoinType.Right) { name and it.city.match(right.origin) } + typed.fullJoin(typed2) { name and it.city.match(right.origin) } shouldBe typed.join(typed2, JoinType.Full) { name and it.city.match(right.origin) } + typed.excludeJoin(typed2) { city.match(right.origin) } shouldBe typed.join(typed2, JoinType.Exclude) { city.match(right.origin) } + typed.filterJoin(typed2) { city.match(right.origin) } shouldBe typed.join(typed2, JoinType.Filter) { city.match(right.origin) } + } } diff --git a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/join.kt b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/join.kt index 6fd14236b4..c985766b28 100644 --- a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/join.kt +++ b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/join.kt @@ -10,7 +10,9 @@ public fun DataFrame.join( other: DataFrame, type: JoinType = JoinType.Inner, selector: JoinColumnsSelector? = null -): DataFrame = joinImpl(other, type, true, selector) +): DataFrame { + return joinImpl(other, type, addNewColumns = type.addNewColumns, selector) +} public fun DataFrame.join( other: DataFrame, @@ -116,10 +118,17 @@ public enum class JoinType { Left, // all data from left data frame, nulls for mismatches in right data frame Right, // all data from right data frame, nulls for mismatches in left data frame Inner, // only matched data from right and left data frame + Filter, // only matched data from left data frame Full, // all data from left and from right data frame, nulls for any mismatches Exclude // mismatched rows from left data frame } +internal val JoinType.addNewColumns: Boolean + get() = when (this) { + JoinType.Filter, JoinType.Exclude -> false + JoinType.Left, JoinType.Right, JoinType.Inner, JoinType.Full -> true + } + public val JoinType.allowLeftNulls: Boolean get() = this == JoinType.Right || this == JoinType.Full public val JoinType.allowRightNulls: Boolean get() = this == JoinType.Left || this == JoinType.Full || this == JoinType.Exclude diff --git a/core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/testSets/person/BaseJoinTest.kt b/core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/testSets/person/BaseJoinTest.kt new file mode 100644 index 0000000000..8e0f2e790c --- /dev/null +++ b/core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/testSets/person/BaseJoinTest.kt @@ -0,0 +1,26 @@ +package org.jetbrains.kotlinx.dataframe.testSets.person + +import org.jetbrains.kotlinx.dataframe.DataFrame +import org.jetbrains.kotlinx.dataframe.annotations.DataSchema +import org.jetbrains.kotlinx.dataframe.api.cast +import org.jetbrains.kotlinx.dataframe.api.dataFrameOf + +open class BaseJoinTest : BaseTest() { + val df2 = dataFrameOf("name", "origin", "grade", "age")( + "Alice", "London", 3, "young", + "Alice", "London", 5, "old", + "Bob", "Tokyo", 4, "young", + "Bob", "Paris", 5, "old", + "Charlie", "Moscow", 1, "young", + "Charlie", "Moscow", 2, "old", + "Bob", "Paris", 4, null + ) + val typed2: DataFrame = df2.cast() + + @DataSchema + interface Person2 { + val name: String + val origin: String? + val grade: Int + } +} diff --git a/core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/testSets/person/JoinTests.kt b/core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/testSets/person/JoinTests.kt index 47fa300d4c..68962157d8 100644 --- a/core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/testSets/person/JoinTests.kt +++ b/core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/testSets/person/JoinTests.kt @@ -1,49 +1,26 @@ package org.jetbrains.kotlinx.dataframe.testSets.person import io.kotest.matchers.shouldBe -import org.jetbrains.kotlinx.dataframe.DataFrame -import org.jetbrains.kotlinx.dataframe.annotations.DataSchema +import org.jetbrains.kotlinx.dataframe.api.JoinType import org.jetbrains.kotlinx.dataframe.api.addId import org.jetbrains.kotlinx.dataframe.api.all import org.jetbrains.kotlinx.dataframe.api.append -import org.jetbrains.kotlinx.dataframe.api.cast import org.jetbrains.kotlinx.dataframe.api.column import org.jetbrains.kotlinx.dataframe.api.count -import org.jetbrains.kotlinx.dataframe.api.dataFrameOf import org.jetbrains.kotlinx.dataframe.api.distinct import org.jetbrains.kotlinx.dataframe.api.excludeJoin import org.jetbrains.kotlinx.dataframe.api.filter import org.jetbrains.kotlinx.dataframe.api.filterJoin import org.jetbrains.kotlinx.dataframe.api.fullJoin import org.jetbrains.kotlinx.dataframe.api.innerJoin +import org.jetbrains.kotlinx.dataframe.api.join import org.jetbrains.kotlinx.dataframe.api.leftJoin import org.jetbrains.kotlinx.dataframe.api.remove import org.jetbrains.kotlinx.dataframe.api.rightJoin import org.jetbrains.kotlinx.dataframe.api.select import org.junit.Test -class JoinTests : BaseTest() { - - val df2 = dataFrameOf("name", "origin", "grade", "age")( - "Alice", "London", 3, "young", - "Alice", "London", 5, "old", - "Bob", "Tokyo", 4, "young", - "Bob", "Paris", 5, "old", - "Charlie", "Moscow", 1, "young", - "Charlie", "Moscow", 2, "old", - "Bob", "Paris", 4, null - ) - -// Generated Code - - @DataSchema - interface Person2 { - val name: String - val origin: String? - val grade: Int - } - - val typed2: DataFrame = df2.cast() +class JoinTests : BaseJoinTest() { @Test fun `inner join`() { @@ -118,4 +95,14 @@ class JoinTests : BaseTest() { res shouldBe expected } + + @Test + fun `test overloads contract`() { + typed.innerJoin(typed2) { name and it.city.match(right.origin) } shouldBe typed.join(typed2, JoinType.Inner) { name and it.city.match(right.origin) } + typed.leftJoin(typed2) { name and it.city.match(right.origin) } shouldBe typed.join(typed2, JoinType.Left) { name and it.city.match(right.origin) } + typed.rightJoin(typed2) { name and it.city.match(right.origin) } shouldBe typed.join(typed2, JoinType.Right) { name and it.city.match(right.origin) } + typed.fullJoin(typed2) { name and it.city.match(right.origin) } shouldBe typed.join(typed2, JoinType.Full) { name and it.city.match(right.origin) } + typed.excludeJoin(typed2) { city.match(right.origin) } shouldBe typed.join(typed2, JoinType.Exclude) { city.match(right.origin) } + typed.filterJoin(typed2) { city.match(right.origin) } shouldBe typed.join(typed2, JoinType.Filter) { city.match(right.origin) } + } } diff --git a/docs/StardustDocs/topics/join.md b/docs/StardustDocs/topics/join.md index bb20d8e196..e2bc83dbc3 100644 --- a/docs/StardustDocs/topics/join.md +++ b/docs/StardustDocs/topics/join.md @@ -94,6 +94,7 @@ df.join(other) Supported join types: * `Inner` (default) — only matched rows from left and right [`DataFrames`](DataFrame.md) +* `Filter` — only matched rows from left [`DataFrame`](DataFrame.md) * `Left` — all rows from left [`DataFrame`](DataFrame.md), mismatches from right [`DataFrame`](DataFrame.md) filled with `null` * `Right` — all rows from right [`DataFrame`](DataFrame.md), mismatches from left [`DataFrame`](DataFrame.md) filled with `null` * `Full` — all rows from left and right [`DataFrames`](DataFrame.md), any mismatches filled with `null` From 2772a505d4776d1f13459db5890d772c3ef9bc3b Mon Sep 17 00:00:00 2001 From: Nikita Klimenko Date: Mon, 31 Jul 2023 22:29:35 +0300 Subject: [PATCH 25/45] Add predicateJoin operation --- .../kotlinx/dataframe/api/predicateJoin.kt | 50 ++ .../dataframe/impl/api/predicateJoin.kt | 98 ++++ .../explainer/PluginCallbackProxy.kt | 116 +++-- .../dataframe/samples/api/PredicateJoin.kt | 467 ++++++++++++++++++ .../testSets/person/PredicateJoinTests.kt | 130 +++++ .../kotlinx/dataframe/api/predicateJoin.kt | 50 ++ .../dataframe/impl/api/predicateJoin.kt | 98 ++++ .../explainer/PluginCallbackProxy.kt | 116 +++-- .../dataframe/samples/api/PredicateJoin.kt | 467 ++++++++++++++++++ .../testSets/person/PredicateJoinTests.kt | 130 +++++ docs/StardustDocs/d.tree | 1 + .../StardustDocs/topics/multipleDataFrames.md | 1 + docs/StardustDocs/topics/operations.md | 1 + docs/StardustDocs/topics/predicateJoin.md | 286 +++++++++++ 14 files changed, 1907 insertions(+), 104 deletions(-) create mode 100644 core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/predicateJoin.kt create mode 100644 core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/api/predicateJoin.kt create mode 100644 core/generated-sources/src/test/kotlin/org/jetbrains/kotlinx/dataframe/samples/api/PredicateJoin.kt create mode 100644 core/generated-sources/src/test/kotlin/org/jetbrains/kotlinx/dataframe/testSets/person/PredicateJoinTests.kt create mode 100644 core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/predicateJoin.kt create mode 100644 core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/api/predicateJoin.kt create mode 100644 core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/samples/api/PredicateJoin.kt create mode 100644 core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/testSets/person/PredicateJoinTests.kt create mode 100644 docs/StardustDocs/topics/predicateJoin.md diff --git a/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/predicateJoin.kt b/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/predicateJoin.kt new file mode 100644 index 0000000000..1ccd42a52f --- /dev/null +++ b/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/predicateJoin.kt @@ -0,0 +1,50 @@ +package org.jetbrains.kotlinx.dataframe.api + +import org.jetbrains.kotlinx.dataframe.DataFrame +import org.jetbrains.kotlinx.dataframe.DataRow +import org.jetbrains.kotlinx.dataframe.Selector +import org.jetbrains.kotlinx.dataframe.impl.api.predicateJoinImpl + +public interface JoinedDataRow : DataRow { + public val right: DataRow +} + +public typealias JoinExpression = Selector, Boolean> + +public fun DataFrame.predicateJoin( + right: DataFrame, + type: JoinType = JoinType.Inner, + joinExpression: JoinExpression +): DataFrame { + return predicateJoinImpl(right, type, addNewColumns = type.addNewColumns, joinExpression) +} + +public fun DataFrame.innerPredicateJoin( + right: DataFrame, + joinExpression: JoinExpression +): DataFrame = predicateJoin(right, JoinType.Inner, joinExpression) + +public fun DataFrame.leftPredicateJoin( + right: DataFrame, + joinExpression: JoinExpression +): DataFrame = predicateJoin(right, JoinType.Left, joinExpression) + +public fun DataFrame.rightPredicateJoin( + right: DataFrame, + joinExpression: JoinExpression +): DataFrame = predicateJoin(right, JoinType.Right, joinExpression) + +public fun DataFrame.fullPredicateJoin( + right: DataFrame, + joinExpression: JoinExpression +): DataFrame = predicateJoin(right, JoinType.Full, joinExpression) + +public fun DataFrame.filterPredicateJoin( + right: DataFrame, + joinExpression: JoinExpression +): DataFrame = predicateJoinImpl(right, JoinType.Inner, addNewColumns = false, joinExpression) + +public fun DataFrame.excludePredicateJoin( + right: DataFrame, + joinExpression: JoinExpression +): DataFrame = predicateJoinImpl(right, JoinType.Exclude, addNewColumns = false, joinExpression) diff --git a/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/api/predicateJoin.kt b/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/api/predicateJoin.kt new file mode 100644 index 0000000000..701a6875ea --- /dev/null +++ b/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/api/predicateJoin.kt @@ -0,0 +1,98 @@ +package org.jetbrains.kotlinx.dataframe.impl.api + +import org.jetbrains.kotlinx.dataframe.DataColumn +import org.jetbrains.kotlinx.dataframe.DataFrame +import org.jetbrains.kotlinx.dataframe.DataRow +import org.jetbrains.kotlinx.dataframe.api.JoinExpression +import org.jetbrains.kotlinx.dataframe.api.JoinType +import org.jetbrains.kotlinx.dataframe.api.JoinedDataRow +import org.jetbrains.kotlinx.dataframe.api.allowLeftNulls +import org.jetbrains.kotlinx.dataframe.api.allowRightNulls +import org.jetbrains.kotlinx.dataframe.api.cast +import org.jetbrains.kotlinx.dataframe.api.count +import org.jetbrains.kotlinx.dataframe.api.indices +import org.jetbrains.kotlinx.dataframe.api.toDataFrame +import org.jetbrains.kotlinx.dataframe.impl.ColumnNameGenerator +import org.jetbrains.kotlinx.dataframe.impl.DataRowImpl + +internal class JoinedDataRowImpl( + leftOwner: DataFrame, + val index: Int, + rightOwner: DataFrame, + index1: Int +) : JoinedDataRow, DataRowImpl(index, leftOwner) { + override val right: DataRow = DataRowImpl(index1, rightOwner) +} + +internal fun DataFrame.predicateJoinImpl( + right: DataFrame, + type: JoinType = JoinType.Inner, + addNewColumns: Boolean, + joinExpression: JoinExpression +): DataFrame { + val generator = ColumnNameGenerator(columnNames()) + if (addNewColumns) { + right.columnNames().forEach { generator.addUnique(it) } + } + val rightColumnsCount = if (addNewColumns) right.columnsCount() else 0 + val outputData = List(columnsCount() + rightColumnsCount) { mutableListOf() } + val rightMatched = BooleanArray(right.count()) { false } + for (l in indices()) { + var leftMatched = false + for (r in right.indices()) { + val joined = JoinedDataRowImpl(this, l, right, r) + val matched = joinExpression(joined, joined) + if (matched && type == JoinType.Exclude) { + leftMatched = true + break + } + if (matched) { + rightMatched[r] = true + leftMatched = true + val left = get(l).values() + for (col in left.indices) { + outputData[col].add(left[col]) + } + if (addNewColumns) { + val offset = left.size + val row = right.get(r).values() + for (col in row.indices) { + outputData[col + offset].add(row[col]) + } + } + } + } + if (!leftMatched && type.allowRightNulls) { + val left = get(l).values() + for (col in left.indices) { + outputData[col].add(left[col]) + } + if (addNewColumns) { + for (col in left.size..outputData.lastIndex) { + outputData[col].add(null) + } + } + } + } + + if (type.allowLeftNulls) { + rightMatched.forEachIndexed { row, matched -> + if (!matched) { + repeat(columnsCount()) { col -> + outputData[col].add(null) + } + val offset = columnsCount() + val rowData = right[row].values() + for (col in rowData.indices) { + outputData[offset + col].add(rowData[col]) + } + } + } + } + + val df: DataFrame<*> = outputData.mapIndexed { index, values -> + DataColumn.createWithTypeInference(generator.names[index], values) + }.toDataFrame() + + return df.cast() +} diff --git a/core/generated-sources/src/test/kotlin/org/jetbrains/kotlinx/dataframe/explainer/PluginCallbackProxy.kt b/core/generated-sources/src/test/kotlin/org/jetbrains/kotlinx/dataframe/explainer/PluginCallbackProxy.kt index b9da8c9402..c2223087ec 100644 --- a/core/generated-sources/src/test/kotlin/org/jetbrains/kotlinx/dataframe/explainer/PluginCallbackProxy.kt +++ b/core/generated-sources/src/test/kotlin/org/jetbrains/kotlinx/dataframe/explainer/PluginCallbackProxy.kt @@ -52,6 +52,11 @@ object PluginCallbackProxy : PluginCallback { val names = mutableMapOf>() val expressionsByStatement = mutableMapOf>() + private var manualOutput: DataFrameHtmlData? = null + fun overrideHtmlOutput(manualOutput: DataFrameHtmlData) { + this.manualOutput = manualOutput + } + data class Expression( val source: String, val containingClassFqName: String?, @@ -61,69 +66,76 @@ object PluginCallbackProxy : PluginCallback { fun start() { expressionsByStatement.clear() + manualOutput = null } fun save() { // ensure stable table ids across test invocation sessionId = 0 tableInSessionId = 0 - var output = DataFrameHtmlData.tableDefinitions() + DataFrameHtmlData( - // copy writerside stlyles - style = """ - body { - font-family: "JetBrains Mono",SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace; - } - - :root { - color: #19191C; - background-color: #fff; - } - - :root[theme="dark"] { - background-color: #19191C; - color: #FFFFFFCC - } - - details details { - margin-left: 20px; - } - - summary { - padding: 6px; - } - """.trimIndent() - ) + var output: DataFrameHtmlData + val manualOutput = this.manualOutput + if (manualOutput == null) { + output = DataFrameHtmlData.tableDefinitions() + DataFrameHtmlData( + // copy writerside stlyles + style = """ + body { + font-family: "JetBrains Mono",SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace; + } + + :root { + color: #19191C; + background-color: #fff; + } + + :root[theme="dark"] { + background-color: #19191C; + color: #FFFFFFCC + } + + details details { + margin-left: 20px; + } + + summary { + padding: 6px; + } + """.trimIndent() + ) - // make copy to avoid concurrent modification exception - val statements = expressionsByStatement.toMap() - when (statements.size) { - 0 -> error("function doesn't have any dataframe expression") - 1 -> { - output += statementOutput(statements.values.single()) - } - else -> { - statements.forEach { (index, expressions) -> - var details: DataFrameHtmlData = statementOutput(expressions) - - details = details.copy( - body = - """ -
- ${expressions.joinToString(".") { it.source } - .also { - if (it.length > 95) TODO("expression is too long ${it.length}. better to split sample in multiple snippets") - } - .escapeHtmlForIFrame()} - ${details.body} -
-
- """.trimIndent() - ) + // make copy to avoid concurrent modification exception + val statements = expressionsByStatement.toMap() + when (statements.size) { + 0 -> error("function doesn't have any dataframe expression") + 1 -> { + output += statementOutput(statements.values.single()) + } + else -> { + statements.forEach { (index, expressions) -> + var details: DataFrameHtmlData = statementOutput(expressions) - output += details + details = details.copy( + body = + """ +
+ ${expressions.joinToString(".") { it.source } + .also { + if (it.length > 95) TODO("expression is too long ${it.length}. better to split sample in multiple snippets") + } + .escapeHtmlForIFrame()} + ${details.body} +
+
+ """.trimIndent() + ) + output += details + } } } + } else { + output = manualOutput } + val input = expressionsByStatement.values.first().first() val name = "${input.containingClassFqName}.${input.containingFunName}" val destination = File("build/dataframes").also { diff --git a/core/generated-sources/src/test/kotlin/org/jetbrains/kotlinx/dataframe/samples/api/PredicateJoin.kt b/core/generated-sources/src/test/kotlin/org/jetbrains/kotlinx/dataframe/samples/api/PredicateJoin.kt new file mode 100644 index 0000000000..809aa51df6 --- /dev/null +++ b/core/generated-sources/src/test/kotlin/org/jetbrains/kotlinx/dataframe/samples/api/PredicateJoin.kt @@ -0,0 +1,467 @@ +package org.jetbrains.kotlinx.dataframe.samples.api + +import io.kotest.matchers.shouldBe +import kotlinx.datetime.LocalDate +import kotlinx.datetime.toJavaLocalDate +import org.jetbrains.kotlinx.dataframe.AnyFrame +import org.jetbrains.kotlinx.dataframe.DataFrame +import org.jetbrains.kotlinx.dataframe.annotations.DataSchema +import org.jetbrains.kotlinx.dataframe.api.FormattingDSL +import org.jetbrains.kotlinx.dataframe.api.Infer +import org.jetbrains.kotlinx.dataframe.api.JoinedDataRow +import org.jetbrains.kotlinx.dataframe.api.RGBColor +import org.jetbrains.kotlinx.dataframe.api.and +import org.jetbrains.kotlinx.dataframe.api.cast +import org.jetbrains.kotlinx.dataframe.api.colsOf +import org.jetbrains.kotlinx.dataframe.api.column +import org.jetbrains.kotlinx.dataframe.api.convert +import org.jetbrains.kotlinx.dataframe.api.dataFrameOf +import org.jetbrains.kotlinx.dataframe.api.excludePredicateJoin +import org.jetbrains.kotlinx.dataframe.api.filterPredicateJoin +import org.jetbrains.kotlinx.dataframe.api.fullPredicateJoin +import org.jetbrains.kotlinx.dataframe.api.innerPredicateJoin +import org.jetbrains.kotlinx.dataframe.api.leftPredicateJoin +import org.jetbrains.kotlinx.dataframe.api.predicateJoin +import org.jetbrains.kotlinx.dataframe.api.rightPredicateJoin +import org.jetbrains.kotlinx.dataframe.api.with +import org.jetbrains.kotlinx.dataframe.explainer.PluginCallbackProxy +import org.jetbrains.kotlinx.dataframe.explainer.TransformDataFrameExpressions +import org.jetbrains.kotlinx.dataframe.io.DataFrameHtmlData +import org.jetbrains.kotlinx.dataframe.io.DisplayConfiguration +import org.jetbrains.kotlinx.dataframe.io.renderValueForHtml +import org.jetbrains.kotlinx.dataframe.io.toHTML +import org.jetbrains.kotlinx.dataframe.jupyter.ChainedCellRenderer +import org.jetbrains.kotlinx.dataframe.jupyter.DefaultCellRenderer +import org.jetbrains.kotlinx.dataframe.jupyter.RenderedContent +import org.junit.Test +import java.time.format.DateTimeFormatter + +class PredicateJoin { + + @DataSchema + interface Campaigns { + val name: String + val startDate: LocalDate + val endDate: LocalDate + } + + @DataSchema + interface Visits { + val date: LocalDate + val userId: Int + } + + private val campaigns = dataFrameOf("name", "startDate", "endDate")( + "Winter Sale", LocalDate(2023, 1, 1), LocalDate(2023, 1, 31), + "Spring Sale", LocalDate(2023, 4, 1), LocalDate(2023, 4, 30), + "Summer Sale", LocalDate(2023, 7, 1), LocalDate(2023, 7, 31), + "Autumn Sale", LocalDate(2023, 10, 1), LocalDate(2023, 10, 31), + ).cast() + + private val visits = dataFrameOf("date", "usedId")( + LocalDate(2023, 1, 10), 1, + LocalDate(2023, 1, 20), 2, + LocalDate(2023, 4, 15), 1, + LocalDate(2023, 5, 1), 3, + LocalDate(2023, 7, 10), 2, + ).cast() + + class ColoredValue(val value: T, val backgroundColor: RGBColor, val textColor: RGBColor) + + private val renderer = object : ChainedCellRenderer(DefaultCellRenderer) { + override fun maybeContent(value: Any?, configuration: DisplayConfiguration): RenderedContent? { + return if (value is ColoredValue<*>) { + if (value.value is LocalDate) { + RenderedContent.text(DateTimeFormatter.ofPattern("dd MMMM yyyy").format(value.value.toJavaLocalDate())) + } else { + renderValueForHtml(value.value, configuration.cellContentLimit, configuration.decimalFormat) + } + } else { + null + } + } + + override fun maybeTooltip(value: Any?, configuration: DisplayConfiguration): String? { + return null + } + } + + private fun AnyFrame.uwrapColoredValues(): AnyFrame { + return convert { colsOf?>().rec() }.with(Infer.Type) { it?.value } + } + + private fun T.colored(background: RGBColor, text: RGBColor) = ColoredValue(this, background, text) + private fun T.winter(background: RGBColor = RGBColor(179, 205, 224), text: RGBColor = RGBColor(0, 0, 51)) = ColoredValue(this, background, text) + private fun T.spring(background: RGBColor = RGBColor(204, 235, 197), text: RGBColor = RGBColor(0, 51, 0)) = ColoredValue(this, background, text) + private fun T.summer(background: RGBColor = RGBColor(176, 224, 230), text: RGBColor = RGBColor(25, 25, 112)) = ColoredValue(this, background, text) + private fun T.autumn(background: RGBColor = RGBColor(221, 160, 221), text: RGBColor = RGBColor(85, 26, 139)) = ColoredValue(this, background, text) + + private val coloredCampaigns = dataFrameOf("name", "startDate", "endDate")( + "Winter Sale".winter(), LocalDate(2023, 1, 1).winter(), LocalDate(2023, 1, 31).winter(), + "Spring Sale".spring(), LocalDate(2023, 4, 1).spring(), LocalDate(2023, 4, 30).spring(), + "Summer Sale".summer(), LocalDate(2023, 7, 1).summer(), LocalDate(2023, 7, 31).summer(), + "Autumn Sale".autumn(), LocalDate(2023, 10, 1).autumn(), LocalDate(2023, 10, 31).autumn(), + ) + + private val coloredVisits = dataFrameOf("date", "usedId")( + LocalDate(2023, 1, 10).winter(), 1.winter(), + LocalDate(2023, 1, 20).winter(), 2.winter(), + LocalDate(2023, 4, 15).spring(), 1.spring(), + LocalDate(2023, 5, 1).colored(FormattingDSL.white, FormattingDSL.black), 3.colored(FormattingDSL.white, FormattingDSL.black), + LocalDate(2023, 7, 10).summer(), 2.summer(), + ) + + private fun AnyFrame.toColoredHTML() = toHTML( + getFooter = { null }, + cellRenderer = renderer, + configuration = DisplayConfiguration.DEFAULT.copy( + cellFormatter = { row, col -> + val value = row[col] + if (value is ColoredValue<*>) { + background(value.backgroundColor) and textColor(value.textColor) + } else { + background(white) + } + } + ) + ) + + private val joinExpression: JoinedDataRow.(it: JoinedDataRow) -> Boolean = { + right[{ "date">() }].value in + "startDate">().value.."endDate">().value + } + + private fun snippetOutput(coloredResult: DataFrame, result: DataFrame) { + coloredCampaigns.uwrapColoredValues() shouldBe campaigns + coloredVisits.uwrapColoredValues() shouldBe visits + coloredResult.uwrapColoredValues() shouldBe result + + fun DataFrameHtmlData.wrap(title: String): DataFrameHtmlData { + return copy( + body = """ +
+ $title + $body +
+ """.trimIndent() + ) + } + + PluginCallbackProxy.overrideHtmlOutput( + manualOutput = DataFrameHtmlData.tableDefinitions() + .plus(coloredCampaigns.toColoredHTML().wrap("campaigns")) + .plus(coloredVisits.toColoredHTML().wrap("visits")) + .plus(coloredResult.toColoredHTML().wrap("result")) + .plus( + DataFrameHtmlData( + style = """ + body { + display: flex; + align-items: flex-start; + overflow-x: auto; + font-family: "JetBrains Mono", SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace; + font-size: 14px; + } + + :root { + color: #19191C; + background-color: #fff; + } + + :root[theme="dark"] { + background-color: #19191C; + color: #FFFFFFCC + } + + .table-container { + margin-right: 20px; + } + + .table-container:not(:last-child) { + margin-right: 20px; + } + + td { + white-space: nowrap; + } + """.trimIndent() + ) + ) + ) + } + + @TransformDataFrameExpressions + @Test + fun predicateJoin_accessors() { + val result = run { + // SampleStart + val date by column() + val startDate by column() + val endDate by column() + + campaigns.innerPredicateJoin(visits) { + right[date] in startDate()..endDate() + } + // SampleEnd + } + val coloredResult = coloredCampaigns.innerPredicateJoin(coloredVisits, joinExpression = joinExpression) + snippetOutput(coloredResult, result) + } + + @TransformDataFrameExpressions + @Test + fun filterPredicateJoin_accessors() { + val result = run { + // SampleStart + val date by column() + val startDate by column() + val endDate by column() + + campaigns.filterPredicateJoin(visits) { + right[date] in startDate()..endDate() + } + // SampleEnd + } + val coloredResult = coloredCampaigns.filterPredicateJoin(coloredVisits, joinExpression = joinExpression) + snippetOutput(coloredResult, result) + } + + @TransformDataFrameExpressions + @Test + fun leftPredicateJoin_accessors() { + val result = run { + // SampleStart + val date by column() + val startDate by column() + val endDate by column() + + campaigns.leftPredicateJoin(visits) { + right[date] in startDate()..endDate() + } + // SampleEnd + } + val coloredResult = coloredCampaigns.leftPredicateJoin(coloredVisits, joinExpression = joinExpression) + snippetOutput(coloredResult, result) + } + + @TransformDataFrameExpressions + @Test + fun rightPredicateJoin_accessors() { + val result = run { + // SampleStart + val date by column() + val startDate by column() + val endDate by column() + + campaigns.rightPredicateJoin(visits) { + right[date] in startDate()..endDate() + } + // SampleEnd + } + val coloredResult = coloredCampaigns.rightPredicateJoin(coloredVisits, joinExpression = joinExpression) + snippetOutput(coloredResult, result) + } + + @TransformDataFrameExpressions + @Test + fun fullPredicateJoin_accessors() { + val result = run { + // SampleStart + val date by column() + val startDate by column() + val endDate by column() + + campaigns.fullPredicateJoin(visits) { + right[date] in startDate()..endDate() + } + // SampleEnd + } + val coloredResult = coloredCampaigns.fullPredicateJoin(coloredVisits, joinExpression = joinExpression) + snippetOutput(coloredResult, result) + } + + @TransformDataFrameExpressions + @Test + fun excludePredicateJoin_accessors() { + val result = run { + // SampleStart + val date by column() + val startDate by column() + val endDate by column() + + campaigns.excludePredicateJoin(visits) { + right[date] in startDate()..endDate() + } + // SampleEnd + } + val coloredResult = coloredCampaigns.excludePredicateJoin(coloredVisits, joinExpression = joinExpression) + snippetOutput(coloredResult, result) + } + + @TransformDataFrameExpressions + @Test + fun predicateJoin_strings() { + val result = + // SampleStart + campaigns.innerPredicateJoin(visits) { + right[{ "date"() }] in "startDate"().."endDate"() + } + // SampleEnd + val coloredResult = coloredCampaigns.innerPredicateJoin(coloredVisits, joinExpression = joinExpression) + snippetOutput(coloredResult, result) + } + + @TransformDataFrameExpressions + @Test + fun filterPredicateJoin_strings() { + val result = + // SampleStart + campaigns.filterPredicateJoin(visits) { + right[{ "date"() }] in "startDate"().."endDate"() + } + // SampleEnd + val coloredResult = coloredCampaigns.filterPredicateJoin(coloredVisits, joinExpression = joinExpression) + snippetOutput(coloredResult, result) + } + + @TransformDataFrameExpressions + @Test + fun leftPredicateJoin_strings() { + val result = + // SampleStart + campaigns.leftPredicateJoin(visits) { + right[{ "date"() }] in "startDate"().."endDate"() + } + // SampleEnd + val coloredResult = coloredCampaigns.leftPredicateJoin(coloredVisits, joinExpression = joinExpression) + snippetOutput(coloredResult, result) + } + + @TransformDataFrameExpressions + @Test + fun rightPredicateJoin_strings() { + val result = + // SampleStart + campaigns.rightPredicateJoin(visits) { + right[{ "date"() }] in "startDate"().."endDate"() + } + // SampleEnd + val coloredResult = coloredCampaigns.rightPredicateJoin(coloredVisits, joinExpression = joinExpression) + snippetOutput(coloredResult, result) + } + + @TransformDataFrameExpressions + @Test + fun fullPredicateJoin_strings() { + val result = + // SampleStart + campaigns.fullPredicateJoin(visits) { + right[{ "date"() }] in "startDate"().."endDate"() + } + // SampleEnd + val coloredResult = coloredCampaigns.fullPredicateJoin(coloredVisits, joinExpression = joinExpression) + snippetOutput(coloredResult, result) + } + + @TransformDataFrameExpressions + @Test + fun excludePredicateJoin_strings() { + val result = + // SampleStart + campaigns.excludePredicateJoin(visits) { + right[{ "date"() }] in "startDate"().."endDate"() + } + // SampleEnd + val coloredResult = coloredCampaigns.excludePredicateJoin(coloredVisits, joinExpression = joinExpression) + snippetOutput(coloredResult, result) + } + + @TransformDataFrameExpressions + @Test + fun predicateJoin_properties() { + val result = + // SampleStart + campaigns.innerPredicateJoin(visits) { + right.date in startDate..endDate + } + // SampleEnd + val coloredResult = coloredCampaigns.innerPredicateJoin(coloredVisits, joinExpression = joinExpression) + snippetOutput(coloredResult, result) + } + + @TransformDataFrameExpressions + @Test + fun filterPredicateJoin_properties() { + val result = + // SampleStart + campaigns.filterPredicateJoin(visits) { + right.date in startDate..endDate + } + // SampleEnd + val coloredResult = coloredCampaigns.filterPredicateJoin(coloredVisits, joinExpression = joinExpression) + snippetOutput(coloredResult, result) + } + + @TransformDataFrameExpressions + @Test + fun leftPredicateJoin_properties() { + val result = + // SampleStart + campaigns.leftPredicateJoin(visits) { + right.date in startDate..endDate + } + // SampleEnd + val coloredResult = coloredCampaigns.leftPredicateJoin(coloredVisits, joinExpression = joinExpression) + snippetOutput(coloredResult, result) + } + + @TransformDataFrameExpressions + @Test + fun rightPredicateJoin_properties() { + val result = + // SampleStart + campaigns.rightPredicateJoin(visits) { + right.date in startDate..endDate + } + // SampleEnd + val coloredResult = coloredCampaigns.rightPredicateJoin(coloredVisits, joinExpression = joinExpression) + snippetOutput(coloredResult, result) + } + + @TransformDataFrameExpressions + @Test + fun fullPredicateJoin_properties() { + val result = + // SampleStart + campaigns.fullPredicateJoin(visits) { + right.date in startDate..endDate + } + // SampleEnd + val coloredResult = coloredCampaigns.fullPredicateJoin(coloredVisits, joinExpression = joinExpression) + snippetOutput(coloredResult, result) + } + + @TransformDataFrameExpressions + @Test + fun excludePredicateJoin_properties() { + val result = + // SampleStart + campaigns.excludePredicateJoin(visits) { + right.date in startDate..endDate + } + // SampleEnd + val coloredResult = coloredCampaigns.excludePredicateJoin(coloredVisits, joinExpression = joinExpression) + snippetOutput(coloredResult, result) + } + + @TransformDataFrameExpressions + @Test + fun crossProduct() { + val result = + // SampleStart + campaigns.predicateJoin(visits) { true } + // SampleEnd + val coloredResult = coloredCampaigns.predicateJoin(coloredVisits) { true } + snippetOutput(coloredResult, result) + } +} diff --git a/core/generated-sources/src/test/kotlin/org/jetbrains/kotlinx/dataframe/testSets/person/PredicateJoinTests.kt b/core/generated-sources/src/test/kotlin/org/jetbrains/kotlinx/dataframe/testSets/person/PredicateJoinTests.kt new file mode 100644 index 0000000000..5c4d809710 --- /dev/null +++ b/core/generated-sources/src/test/kotlin/org/jetbrains/kotlinx/dataframe/testSets/person/PredicateJoinTests.kt @@ -0,0 +1,130 @@ +package org.jetbrains.kotlinx.dataframe.testSets.person + +import io.kotest.matchers.shouldBe +import org.jetbrains.kotlinx.dataframe.api.JoinType +import org.jetbrains.kotlinx.dataframe.api.addId +import org.jetbrains.kotlinx.dataframe.api.all +import org.jetbrains.kotlinx.dataframe.api.append +import org.jetbrains.kotlinx.dataframe.api.column +import org.jetbrains.kotlinx.dataframe.api.count +import org.jetbrains.kotlinx.dataframe.api.dataFrameOf +import org.jetbrains.kotlinx.dataframe.api.distinct +import org.jetbrains.kotlinx.dataframe.api.excludeJoin +import org.jetbrains.kotlinx.dataframe.api.excludePredicateJoin +import org.jetbrains.kotlinx.dataframe.api.filter +import org.jetbrains.kotlinx.dataframe.api.filterPredicateJoin +import org.jetbrains.kotlinx.dataframe.api.fullPredicateJoin +import org.jetbrains.kotlinx.dataframe.api.innerPredicateJoin +import org.jetbrains.kotlinx.dataframe.api.leftPredicateJoin +import org.jetbrains.kotlinx.dataframe.api.predicateJoin +import org.jetbrains.kotlinx.dataframe.api.print +import org.jetbrains.kotlinx.dataframe.api.remove +import org.jetbrains.kotlinx.dataframe.api.rightPredicateJoin +import org.jetbrains.kotlinx.dataframe.api.select +import org.junit.Test + +class PredicateJoinTests : BaseJoinTest() { + + @Test + fun `inner join`() { + val res = typed.predicateJoin(typed2) { + name == right.name && city == right.origin + } + res.columnsCount() shouldBe 8 + res.rowsCount() shouldBe 7 + res["age1"].hasNulls() shouldBe false + res.count { name == "Charlie" && city == "Moscow" } shouldBe 4 + res.select { city and name }.distinct().rowsCount() shouldBe 3 + res[Person2::grade].hasNulls() shouldBe false + } + + @Test + fun `left join`() { + val res = typed.leftPredicateJoin(typed2) { name == right.name && city == right.origin } + + res.columnsCount() shouldBe 8 + res.rowsCount() shouldBe 10 + res["age1"].hasNulls() shouldBe true + res.select { city and name }.distinct().rowsCount() shouldBe 6 + res.count { it["grade"] == null } shouldBe 3 + res.age.hasNulls() shouldBe false + } + + @Test + fun `right join`() { + val res = typed.rightPredicateJoin(typed2) { + name == right.name && city == right.origin + } + res.columnsCount() shouldBe 8 + res.rowsCount() shouldBe 9 + res["age1"].hasNulls() shouldBe true + res.select { city and name }.distinct().rowsCount() shouldBe 4 + res[Person2::grade].hasNulls() shouldBe false + res.age.hasNulls() shouldBe true + val newEntries = res.filter { it["age"] == null } + newEntries.rowsCount() shouldBe 2 + newEntries.all { it["name1"] == "Bob" && it["origin"] == "Paris" && weight == null } shouldBe true + } + + @Test + fun `outer join`() { + val res = typed.fullPredicateJoin(typed2) { name == right.name && city == right.origin } + println(res) + res.columnsCount() shouldBe 8 + res.rowsCount() shouldBe 12 + res.columns().all { it.hasNulls() } shouldBe true + res.select { city and name }.distinct().rowsCount() shouldBe 7 + val distinct = res.select { name and age and city and weight }.distinct() + val expected = typed.append(null, null, null, null) + distinct shouldBe expected + } + + @Test + fun `filter join`() { + val res = typed.filterPredicateJoin(typed2) { city == right.origin } + val expected = typed.innerPredicateJoin(typed2.select { origin }) { city == right.origin }.remove("origin") + res shouldBe expected + } + + @Test + fun `filter not join`() { + val res = typed.excludePredicateJoin(typed2) { city == right.origin } + res.rowsCount() shouldBe 3 + res.city.toSet() shouldBe typed.city.toSet() - typed2.origin.toSet() + + val indexColumn = column("__index__") + val withIndex = typed.addId(indexColumn) + val joined = withIndex.filterPredicateJoin(typed2) { city == right.origin } + val joinedIndices = joined[indexColumn].toSet() + val expected = withIndex.filter { !joinedIndices.contains(it[indexColumn]) }.remove(indexColumn) + + res shouldBe expected + } + + @Test + fun rightJoin() { + val df = dataFrameOf("a", "b")( + 1, "a", + 2, "b", + 3, "c", + ) + + val df1 = dataFrameOf("a", "c")( + 5, "V", + 1, "I", + 2, "II", + 3, "III", + ) + df.append(4, "e").excludeJoin(df1).print() + } + + @Test + fun `test overloads contract`() { + typed.innerPredicateJoin(typed2) { name == right.name && city == right.origin } shouldBe typed.predicateJoin(typed2, JoinType.Inner) { name == right.name && city == right.origin } + typed.leftPredicateJoin(typed2) { name == right.name && city == right.origin } shouldBe typed.predicateJoin(typed2, JoinType.Left) { name == right.name && city == right.origin } + typed.rightPredicateJoin(typed2) { name == right.name && city == right.origin } shouldBe typed.predicateJoin(typed2, JoinType.Right) { name == right.name && city == right.origin } + typed.fullPredicateJoin(typed2) { name == right.name && city == right.origin } shouldBe typed.predicateJoin(typed2, JoinType.Full) { name == right.name && city == right.origin } + typed.excludePredicateJoin(typed2) { city == right.origin } shouldBe typed.predicateJoin(typed2, JoinType.Exclude) { city == right.origin } + typed.filterPredicateJoin(typed2) { city == right.origin } shouldBe typed.predicateJoin(typed2, JoinType.Filter) { city == right.origin } + } +} diff --git a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/predicateJoin.kt b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/predicateJoin.kt new file mode 100644 index 0000000000..1ccd42a52f --- /dev/null +++ b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/predicateJoin.kt @@ -0,0 +1,50 @@ +package org.jetbrains.kotlinx.dataframe.api + +import org.jetbrains.kotlinx.dataframe.DataFrame +import org.jetbrains.kotlinx.dataframe.DataRow +import org.jetbrains.kotlinx.dataframe.Selector +import org.jetbrains.kotlinx.dataframe.impl.api.predicateJoinImpl + +public interface JoinedDataRow : DataRow
{ + public val right: DataRow +} + +public typealias JoinExpression = Selector, Boolean> + +public fun DataFrame.predicateJoin( + right: DataFrame, + type: JoinType = JoinType.Inner, + joinExpression: JoinExpression +): DataFrame { + return predicateJoinImpl(right, type, addNewColumns = type.addNewColumns, joinExpression) +} + +public fun DataFrame.innerPredicateJoin( + right: DataFrame, + joinExpression: JoinExpression +): DataFrame = predicateJoin(right, JoinType.Inner, joinExpression) + +public fun DataFrame.leftPredicateJoin( + right: DataFrame, + joinExpression: JoinExpression +): DataFrame = predicateJoin(right, JoinType.Left, joinExpression) + +public fun DataFrame.rightPredicateJoin( + right: DataFrame, + joinExpression: JoinExpression +): DataFrame = predicateJoin(right, JoinType.Right, joinExpression) + +public fun DataFrame.fullPredicateJoin( + right: DataFrame, + joinExpression: JoinExpression +): DataFrame = predicateJoin(right, JoinType.Full, joinExpression) + +public fun DataFrame.filterPredicateJoin( + right: DataFrame, + joinExpression: JoinExpression +): DataFrame = predicateJoinImpl(right, JoinType.Inner, addNewColumns = false, joinExpression) + +public fun DataFrame.excludePredicateJoin( + right: DataFrame, + joinExpression: JoinExpression +): DataFrame = predicateJoinImpl(right, JoinType.Exclude, addNewColumns = false, joinExpression) diff --git a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/api/predicateJoin.kt b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/api/predicateJoin.kt new file mode 100644 index 0000000000..701a6875ea --- /dev/null +++ b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/api/predicateJoin.kt @@ -0,0 +1,98 @@ +package org.jetbrains.kotlinx.dataframe.impl.api + +import org.jetbrains.kotlinx.dataframe.DataColumn +import org.jetbrains.kotlinx.dataframe.DataFrame +import org.jetbrains.kotlinx.dataframe.DataRow +import org.jetbrains.kotlinx.dataframe.api.JoinExpression +import org.jetbrains.kotlinx.dataframe.api.JoinType +import org.jetbrains.kotlinx.dataframe.api.JoinedDataRow +import org.jetbrains.kotlinx.dataframe.api.allowLeftNulls +import org.jetbrains.kotlinx.dataframe.api.allowRightNulls +import org.jetbrains.kotlinx.dataframe.api.cast +import org.jetbrains.kotlinx.dataframe.api.count +import org.jetbrains.kotlinx.dataframe.api.indices +import org.jetbrains.kotlinx.dataframe.api.toDataFrame +import org.jetbrains.kotlinx.dataframe.impl.ColumnNameGenerator +import org.jetbrains.kotlinx.dataframe.impl.DataRowImpl + +internal class JoinedDataRowImpl( + leftOwner: DataFrame, + val index: Int, + rightOwner: DataFrame, + index1: Int +) : JoinedDataRow, DataRowImpl(index, leftOwner) { + override val right: DataRow = DataRowImpl(index1, rightOwner) +} + +internal fun DataFrame.predicateJoinImpl( + right: DataFrame, + type: JoinType = JoinType.Inner, + addNewColumns: Boolean, + joinExpression: JoinExpression +): DataFrame { + val generator = ColumnNameGenerator(columnNames()) + if (addNewColumns) { + right.columnNames().forEach { generator.addUnique(it) } + } + val rightColumnsCount = if (addNewColumns) right.columnsCount() else 0 + val outputData = List(columnsCount() + rightColumnsCount) { mutableListOf() } + val rightMatched = BooleanArray(right.count()) { false } + for (l in indices()) { + var leftMatched = false + for (r in right.indices()) { + val joined = JoinedDataRowImpl(this, l, right, r) + val matched = joinExpression(joined, joined) + if (matched && type == JoinType.Exclude) { + leftMatched = true + break + } + if (matched) { + rightMatched[r] = true + leftMatched = true + val left = get(l).values() + for (col in left.indices) { + outputData[col].add(left[col]) + } + if (addNewColumns) { + val offset = left.size + val row = right.get(r).values() + for (col in row.indices) { + outputData[col + offset].add(row[col]) + } + } + } + } + if (!leftMatched && type.allowRightNulls) { + val left = get(l).values() + for (col in left.indices) { + outputData[col].add(left[col]) + } + if (addNewColumns) { + for (col in left.size..outputData.lastIndex) { + outputData[col].add(null) + } + } + } + } + + if (type.allowLeftNulls) { + rightMatched.forEachIndexed { row, matched -> + if (!matched) { + repeat(columnsCount()) { col -> + outputData[col].add(null) + } + val offset = columnsCount() + val rowData = right[row].values() + for (col in rowData.indices) { + outputData[offset + col].add(rowData[col]) + } + } + } + } + + val df: DataFrame<*> = outputData.mapIndexed { index, values -> + DataColumn.createWithTypeInference(generator.names[index], values) + }.toDataFrame() + + return df.cast() +} diff --git a/core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/explainer/PluginCallbackProxy.kt b/core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/explainer/PluginCallbackProxy.kt index b9da8c9402..c2223087ec 100644 --- a/core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/explainer/PluginCallbackProxy.kt +++ b/core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/explainer/PluginCallbackProxy.kt @@ -52,6 +52,11 @@ object PluginCallbackProxy : PluginCallback { val names = mutableMapOf>() val expressionsByStatement = mutableMapOf>() + private var manualOutput: DataFrameHtmlData? = null + fun overrideHtmlOutput(manualOutput: DataFrameHtmlData) { + this.manualOutput = manualOutput + } + data class Expression( val source: String, val containingClassFqName: String?, @@ -61,69 +66,76 @@ object PluginCallbackProxy : PluginCallback { fun start() { expressionsByStatement.clear() + manualOutput = null } fun save() { // ensure stable table ids across test invocation sessionId = 0 tableInSessionId = 0 - var output = DataFrameHtmlData.tableDefinitions() + DataFrameHtmlData( - // copy writerside stlyles - style = """ - body { - font-family: "JetBrains Mono",SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace; - } - - :root { - color: #19191C; - background-color: #fff; - } - - :root[theme="dark"] { - background-color: #19191C; - color: #FFFFFFCC - } - - details details { - margin-left: 20px; - } - - summary { - padding: 6px; - } - """.trimIndent() - ) + var output: DataFrameHtmlData + val manualOutput = this.manualOutput + if (manualOutput == null) { + output = DataFrameHtmlData.tableDefinitions() + DataFrameHtmlData( + // copy writerside stlyles + style = """ + body { + font-family: "JetBrains Mono",SFMono-Regular,Consolas,"Liberation Mono",Menlo,Courier,monospace; + } + + :root { + color: #19191C; + background-color: #fff; + } + + :root[theme="dark"] { + background-color: #19191C; + color: #FFFFFFCC + } + + details details { + margin-left: 20px; + } + + summary { + padding: 6px; + } + """.trimIndent() + ) - // make copy to avoid concurrent modification exception - val statements = expressionsByStatement.toMap() - when (statements.size) { - 0 -> error("function doesn't have any dataframe expression") - 1 -> { - output += statementOutput(statements.values.single()) - } - else -> { - statements.forEach { (index, expressions) -> - var details: DataFrameHtmlData = statementOutput(expressions) - - details = details.copy( - body = - """ -
- ${expressions.joinToString(".") { it.source } - .also { - if (it.length > 95) TODO("expression is too long ${it.length}. better to split sample in multiple snippets") - } - .escapeHtmlForIFrame()} - ${details.body} -
-
- """.trimIndent() - ) + // make copy to avoid concurrent modification exception + val statements = expressionsByStatement.toMap() + when (statements.size) { + 0 -> error("function doesn't have any dataframe expression") + 1 -> { + output += statementOutput(statements.values.single()) + } + else -> { + statements.forEach { (index, expressions) -> + var details: DataFrameHtmlData = statementOutput(expressions) - output += details + details = details.copy( + body = + """ +
+ ${expressions.joinToString(".") { it.source } + .also { + if (it.length > 95) TODO("expression is too long ${it.length}. better to split sample in multiple snippets") + } + .escapeHtmlForIFrame()} + ${details.body} +
+
+ """.trimIndent() + ) + output += details + } } } + } else { + output = manualOutput } + val input = expressionsByStatement.values.first().first() val name = "${input.containingClassFqName}.${input.containingFunName}" val destination = File("build/dataframes").also { diff --git a/core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/samples/api/PredicateJoin.kt b/core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/samples/api/PredicateJoin.kt new file mode 100644 index 0000000000..809aa51df6 --- /dev/null +++ b/core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/samples/api/PredicateJoin.kt @@ -0,0 +1,467 @@ +package org.jetbrains.kotlinx.dataframe.samples.api + +import io.kotest.matchers.shouldBe +import kotlinx.datetime.LocalDate +import kotlinx.datetime.toJavaLocalDate +import org.jetbrains.kotlinx.dataframe.AnyFrame +import org.jetbrains.kotlinx.dataframe.DataFrame +import org.jetbrains.kotlinx.dataframe.annotations.DataSchema +import org.jetbrains.kotlinx.dataframe.api.FormattingDSL +import org.jetbrains.kotlinx.dataframe.api.Infer +import org.jetbrains.kotlinx.dataframe.api.JoinedDataRow +import org.jetbrains.kotlinx.dataframe.api.RGBColor +import org.jetbrains.kotlinx.dataframe.api.and +import org.jetbrains.kotlinx.dataframe.api.cast +import org.jetbrains.kotlinx.dataframe.api.colsOf +import org.jetbrains.kotlinx.dataframe.api.column +import org.jetbrains.kotlinx.dataframe.api.convert +import org.jetbrains.kotlinx.dataframe.api.dataFrameOf +import org.jetbrains.kotlinx.dataframe.api.excludePredicateJoin +import org.jetbrains.kotlinx.dataframe.api.filterPredicateJoin +import org.jetbrains.kotlinx.dataframe.api.fullPredicateJoin +import org.jetbrains.kotlinx.dataframe.api.innerPredicateJoin +import org.jetbrains.kotlinx.dataframe.api.leftPredicateJoin +import org.jetbrains.kotlinx.dataframe.api.predicateJoin +import org.jetbrains.kotlinx.dataframe.api.rightPredicateJoin +import org.jetbrains.kotlinx.dataframe.api.with +import org.jetbrains.kotlinx.dataframe.explainer.PluginCallbackProxy +import org.jetbrains.kotlinx.dataframe.explainer.TransformDataFrameExpressions +import org.jetbrains.kotlinx.dataframe.io.DataFrameHtmlData +import org.jetbrains.kotlinx.dataframe.io.DisplayConfiguration +import org.jetbrains.kotlinx.dataframe.io.renderValueForHtml +import org.jetbrains.kotlinx.dataframe.io.toHTML +import org.jetbrains.kotlinx.dataframe.jupyter.ChainedCellRenderer +import org.jetbrains.kotlinx.dataframe.jupyter.DefaultCellRenderer +import org.jetbrains.kotlinx.dataframe.jupyter.RenderedContent +import org.junit.Test +import java.time.format.DateTimeFormatter + +class PredicateJoin { + + @DataSchema + interface Campaigns { + val name: String + val startDate: LocalDate + val endDate: LocalDate + } + + @DataSchema + interface Visits { + val date: LocalDate + val userId: Int + } + + private val campaigns = dataFrameOf("name", "startDate", "endDate")( + "Winter Sale", LocalDate(2023, 1, 1), LocalDate(2023, 1, 31), + "Spring Sale", LocalDate(2023, 4, 1), LocalDate(2023, 4, 30), + "Summer Sale", LocalDate(2023, 7, 1), LocalDate(2023, 7, 31), + "Autumn Sale", LocalDate(2023, 10, 1), LocalDate(2023, 10, 31), + ).cast() + + private val visits = dataFrameOf("date", "usedId")( + LocalDate(2023, 1, 10), 1, + LocalDate(2023, 1, 20), 2, + LocalDate(2023, 4, 15), 1, + LocalDate(2023, 5, 1), 3, + LocalDate(2023, 7, 10), 2, + ).cast() + + class ColoredValue(val value: T, val backgroundColor: RGBColor, val textColor: RGBColor) + + private val renderer = object : ChainedCellRenderer(DefaultCellRenderer) { + override fun maybeContent(value: Any?, configuration: DisplayConfiguration): RenderedContent? { + return if (value is ColoredValue<*>) { + if (value.value is LocalDate) { + RenderedContent.text(DateTimeFormatter.ofPattern("dd MMMM yyyy").format(value.value.toJavaLocalDate())) + } else { + renderValueForHtml(value.value, configuration.cellContentLimit, configuration.decimalFormat) + } + } else { + null + } + } + + override fun maybeTooltip(value: Any?, configuration: DisplayConfiguration): String? { + return null + } + } + + private fun AnyFrame.uwrapColoredValues(): AnyFrame { + return convert { colsOf?>().rec() }.with(Infer.Type) { it?.value } + } + + private fun T.colored(background: RGBColor, text: RGBColor) = ColoredValue(this, background, text) + private fun T.winter(background: RGBColor = RGBColor(179, 205, 224), text: RGBColor = RGBColor(0, 0, 51)) = ColoredValue(this, background, text) + private fun T.spring(background: RGBColor = RGBColor(204, 235, 197), text: RGBColor = RGBColor(0, 51, 0)) = ColoredValue(this, background, text) + private fun T.summer(background: RGBColor = RGBColor(176, 224, 230), text: RGBColor = RGBColor(25, 25, 112)) = ColoredValue(this, background, text) + private fun T.autumn(background: RGBColor = RGBColor(221, 160, 221), text: RGBColor = RGBColor(85, 26, 139)) = ColoredValue(this, background, text) + + private val coloredCampaigns = dataFrameOf("name", "startDate", "endDate")( + "Winter Sale".winter(), LocalDate(2023, 1, 1).winter(), LocalDate(2023, 1, 31).winter(), + "Spring Sale".spring(), LocalDate(2023, 4, 1).spring(), LocalDate(2023, 4, 30).spring(), + "Summer Sale".summer(), LocalDate(2023, 7, 1).summer(), LocalDate(2023, 7, 31).summer(), + "Autumn Sale".autumn(), LocalDate(2023, 10, 1).autumn(), LocalDate(2023, 10, 31).autumn(), + ) + + private val coloredVisits = dataFrameOf("date", "usedId")( + LocalDate(2023, 1, 10).winter(), 1.winter(), + LocalDate(2023, 1, 20).winter(), 2.winter(), + LocalDate(2023, 4, 15).spring(), 1.spring(), + LocalDate(2023, 5, 1).colored(FormattingDSL.white, FormattingDSL.black), 3.colored(FormattingDSL.white, FormattingDSL.black), + LocalDate(2023, 7, 10).summer(), 2.summer(), + ) + + private fun AnyFrame.toColoredHTML() = toHTML( + getFooter = { null }, + cellRenderer = renderer, + configuration = DisplayConfiguration.DEFAULT.copy( + cellFormatter = { row, col -> + val value = row[col] + if (value is ColoredValue<*>) { + background(value.backgroundColor) and textColor(value.textColor) + } else { + background(white) + } + } + ) + ) + + private val joinExpression: JoinedDataRow.(it: JoinedDataRow) -> Boolean = { + right[{ "date">() }].value in + "startDate">().value.."endDate">().value + } + + private fun snippetOutput(coloredResult: DataFrame, result: DataFrame) { + coloredCampaigns.uwrapColoredValues() shouldBe campaigns + coloredVisits.uwrapColoredValues() shouldBe visits + coloredResult.uwrapColoredValues() shouldBe result + + fun DataFrameHtmlData.wrap(title: String): DataFrameHtmlData { + return copy( + body = """ +
+ $title + $body +
+ """.trimIndent() + ) + } + + PluginCallbackProxy.overrideHtmlOutput( + manualOutput = DataFrameHtmlData.tableDefinitions() + .plus(coloredCampaigns.toColoredHTML().wrap("campaigns")) + .plus(coloredVisits.toColoredHTML().wrap("visits")) + .plus(coloredResult.toColoredHTML().wrap("result")) + .plus( + DataFrameHtmlData( + style = """ + body { + display: flex; + align-items: flex-start; + overflow-x: auto; + font-family: "JetBrains Mono", SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace; + font-size: 14px; + } + + :root { + color: #19191C; + background-color: #fff; + } + + :root[theme="dark"] { + background-color: #19191C; + color: #FFFFFFCC + } + + .table-container { + margin-right: 20px; + } + + .table-container:not(:last-child) { + margin-right: 20px; + } + + td { + white-space: nowrap; + } + """.trimIndent() + ) + ) + ) + } + + @TransformDataFrameExpressions + @Test + fun predicateJoin_accessors() { + val result = run { + // SampleStart + val date by column() + val startDate by column() + val endDate by column() + + campaigns.innerPredicateJoin(visits) { + right[date] in startDate()..endDate() + } + // SampleEnd + } + val coloredResult = coloredCampaigns.innerPredicateJoin(coloredVisits, joinExpression = joinExpression) + snippetOutput(coloredResult, result) + } + + @TransformDataFrameExpressions + @Test + fun filterPredicateJoin_accessors() { + val result = run { + // SampleStart + val date by column() + val startDate by column() + val endDate by column() + + campaigns.filterPredicateJoin(visits) { + right[date] in startDate()..endDate() + } + // SampleEnd + } + val coloredResult = coloredCampaigns.filterPredicateJoin(coloredVisits, joinExpression = joinExpression) + snippetOutput(coloredResult, result) + } + + @TransformDataFrameExpressions + @Test + fun leftPredicateJoin_accessors() { + val result = run { + // SampleStart + val date by column() + val startDate by column() + val endDate by column() + + campaigns.leftPredicateJoin(visits) { + right[date] in startDate()..endDate() + } + // SampleEnd + } + val coloredResult = coloredCampaigns.leftPredicateJoin(coloredVisits, joinExpression = joinExpression) + snippetOutput(coloredResult, result) + } + + @TransformDataFrameExpressions + @Test + fun rightPredicateJoin_accessors() { + val result = run { + // SampleStart + val date by column() + val startDate by column() + val endDate by column() + + campaigns.rightPredicateJoin(visits) { + right[date] in startDate()..endDate() + } + // SampleEnd + } + val coloredResult = coloredCampaigns.rightPredicateJoin(coloredVisits, joinExpression = joinExpression) + snippetOutput(coloredResult, result) + } + + @TransformDataFrameExpressions + @Test + fun fullPredicateJoin_accessors() { + val result = run { + // SampleStart + val date by column() + val startDate by column() + val endDate by column() + + campaigns.fullPredicateJoin(visits) { + right[date] in startDate()..endDate() + } + // SampleEnd + } + val coloredResult = coloredCampaigns.fullPredicateJoin(coloredVisits, joinExpression = joinExpression) + snippetOutput(coloredResult, result) + } + + @TransformDataFrameExpressions + @Test + fun excludePredicateJoin_accessors() { + val result = run { + // SampleStart + val date by column() + val startDate by column() + val endDate by column() + + campaigns.excludePredicateJoin(visits) { + right[date] in startDate()..endDate() + } + // SampleEnd + } + val coloredResult = coloredCampaigns.excludePredicateJoin(coloredVisits, joinExpression = joinExpression) + snippetOutput(coloredResult, result) + } + + @TransformDataFrameExpressions + @Test + fun predicateJoin_strings() { + val result = + // SampleStart + campaigns.innerPredicateJoin(visits) { + right[{ "date"() }] in "startDate"().."endDate"() + } + // SampleEnd + val coloredResult = coloredCampaigns.innerPredicateJoin(coloredVisits, joinExpression = joinExpression) + snippetOutput(coloredResult, result) + } + + @TransformDataFrameExpressions + @Test + fun filterPredicateJoin_strings() { + val result = + // SampleStart + campaigns.filterPredicateJoin(visits) { + right[{ "date"() }] in "startDate"().."endDate"() + } + // SampleEnd + val coloredResult = coloredCampaigns.filterPredicateJoin(coloredVisits, joinExpression = joinExpression) + snippetOutput(coloredResult, result) + } + + @TransformDataFrameExpressions + @Test + fun leftPredicateJoin_strings() { + val result = + // SampleStart + campaigns.leftPredicateJoin(visits) { + right[{ "date"() }] in "startDate"().."endDate"() + } + // SampleEnd + val coloredResult = coloredCampaigns.leftPredicateJoin(coloredVisits, joinExpression = joinExpression) + snippetOutput(coloredResult, result) + } + + @TransformDataFrameExpressions + @Test + fun rightPredicateJoin_strings() { + val result = + // SampleStart + campaigns.rightPredicateJoin(visits) { + right[{ "date"() }] in "startDate"().."endDate"() + } + // SampleEnd + val coloredResult = coloredCampaigns.rightPredicateJoin(coloredVisits, joinExpression = joinExpression) + snippetOutput(coloredResult, result) + } + + @TransformDataFrameExpressions + @Test + fun fullPredicateJoin_strings() { + val result = + // SampleStart + campaigns.fullPredicateJoin(visits) { + right[{ "date"() }] in "startDate"().."endDate"() + } + // SampleEnd + val coloredResult = coloredCampaigns.fullPredicateJoin(coloredVisits, joinExpression = joinExpression) + snippetOutput(coloredResult, result) + } + + @TransformDataFrameExpressions + @Test + fun excludePredicateJoin_strings() { + val result = + // SampleStart + campaigns.excludePredicateJoin(visits) { + right[{ "date"() }] in "startDate"().."endDate"() + } + // SampleEnd + val coloredResult = coloredCampaigns.excludePredicateJoin(coloredVisits, joinExpression = joinExpression) + snippetOutput(coloredResult, result) + } + + @TransformDataFrameExpressions + @Test + fun predicateJoin_properties() { + val result = + // SampleStart + campaigns.innerPredicateJoin(visits) { + right.date in startDate..endDate + } + // SampleEnd + val coloredResult = coloredCampaigns.innerPredicateJoin(coloredVisits, joinExpression = joinExpression) + snippetOutput(coloredResult, result) + } + + @TransformDataFrameExpressions + @Test + fun filterPredicateJoin_properties() { + val result = + // SampleStart + campaigns.filterPredicateJoin(visits) { + right.date in startDate..endDate + } + // SampleEnd + val coloredResult = coloredCampaigns.filterPredicateJoin(coloredVisits, joinExpression = joinExpression) + snippetOutput(coloredResult, result) + } + + @TransformDataFrameExpressions + @Test + fun leftPredicateJoin_properties() { + val result = + // SampleStart + campaigns.leftPredicateJoin(visits) { + right.date in startDate..endDate + } + // SampleEnd + val coloredResult = coloredCampaigns.leftPredicateJoin(coloredVisits, joinExpression = joinExpression) + snippetOutput(coloredResult, result) + } + + @TransformDataFrameExpressions + @Test + fun rightPredicateJoin_properties() { + val result = + // SampleStart + campaigns.rightPredicateJoin(visits) { + right.date in startDate..endDate + } + // SampleEnd + val coloredResult = coloredCampaigns.rightPredicateJoin(coloredVisits, joinExpression = joinExpression) + snippetOutput(coloredResult, result) + } + + @TransformDataFrameExpressions + @Test + fun fullPredicateJoin_properties() { + val result = + // SampleStart + campaigns.fullPredicateJoin(visits) { + right.date in startDate..endDate + } + // SampleEnd + val coloredResult = coloredCampaigns.fullPredicateJoin(coloredVisits, joinExpression = joinExpression) + snippetOutput(coloredResult, result) + } + + @TransformDataFrameExpressions + @Test + fun excludePredicateJoin_properties() { + val result = + // SampleStart + campaigns.excludePredicateJoin(visits) { + right.date in startDate..endDate + } + // SampleEnd + val coloredResult = coloredCampaigns.excludePredicateJoin(coloredVisits, joinExpression = joinExpression) + snippetOutput(coloredResult, result) + } + + @TransformDataFrameExpressions + @Test + fun crossProduct() { + val result = + // SampleStart + campaigns.predicateJoin(visits) { true } + // SampleEnd + val coloredResult = coloredCampaigns.predicateJoin(coloredVisits) { true } + snippetOutput(coloredResult, result) + } +} diff --git a/core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/testSets/person/PredicateJoinTests.kt b/core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/testSets/person/PredicateJoinTests.kt new file mode 100644 index 0000000000..5c4d809710 --- /dev/null +++ b/core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/testSets/person/PredicateJoinTests.kt @@ -0,0 +1,130 @@ +package org.jetbrains.kotlinx.dataframe.testSets.person + +import io.kotest.matchers.shouldBe +import org.jetbrains.kotlinx.dataframe.api.JoinType +import org.jetbrains.kotlinx.dataframe.api.addId +import org.jetbrains.kotlinx.dataframe.api.all +import org.jetbrains.kotlinx.dataframe.api.append +import org.jetbrains.kotlinx.dataframe.api.column +import org.jetbrains.kotlinx.dataframe.api.count +import org.jetbrains.kotlinx.dataframe.api.dataFrameOf +import org.jetbrains.kotlinx.dataframe.api.distinct +import org.jetbrains.kotlinx.dataframe.api.excludeJoin +import org.jetbrains.kotlinx.dataframe.api.excludePredicateJoin +import org.jetbrains.kotlinx.dataframe.api.filter +import org.jetbrains.kotlinx.dataframe.api.filterPredicateJoin +import org.jetbrains.kotlinx.dataframe.api.fullPredicateJoin +import org.jetbrains.kotlinx.dataframe.api.innerPredicateJoin +import org.jetbrains.kotlinx.dataframe.api.leftPredicateJoin +import org.jetbrains.kotlinx.dataframe.api.predicateJoin +import org.jetbrains.kotlinx.dataframe.api.print +import org.jetbrains.kotlinx.dataframe.api.remove +import org.jetbrains.kotlinx.dataframe.api.rightPredicateJoin +import org.jetbrains.kotlinx.dataframe.api.select +import org.junit.Test + +class PredicateJoinTests : BaseJoinTest() { + + @Test + fun `inner join`() { + val res = typed.predicateJoin(typed2) { + name == right.name && city == right.origin + } + res.columnsCount() shouldBe 8 + res.rowsCount() shouldBe 7 + res["age1"].hasNulls() shouldBe false + res.count { name == "Charlie" && city == "Moscow" } shouldBe 4 + res.select { city and name }.distinct().rowsCount() shouldBe 3 + res[Person2::grade].hasNulls() shouldBe false + } + + @Test + fun `left join`() { + val res = typed.leftPredicateJoin(typed2) { name == right.name && city == right.origin } + + res.columnsCount() shouldBe 8 + res.rowsCount() shouldBe 10 + res["age1"].hasNulls() shouldBe true + res.select { city and name }.distinct().rowsCount() shouldBe 6 + res.count { it["grade"] == null } shouldBe 3 + res.age.hasNulls() shouldBe false + } + + @Test + fun `right join`() { + val res = typed.rightPredicateJoin(typed2) { + name == right.name && city == right.origin + } + res.columnsCount() shouldBe 8 + res.rowsCount() shouldBe 9 + res["age1"].hasNulls() shouldBe true + res.select { city and name }.distinct().rowsCount() shouldBe 4 + res[Person2::grade].hasNulls() shouldBe false + res.age.hasNulls() shouldBe true + val newEntries = res.filter { it["age"] == null } + newEntries.rowsCount() shouldBe 2 + newEntries.all { it["name1"] == "Bob" && it["origin"] == "Paris" && weight == null } shouldBe true + } + + @Test + fun `outer join`() { + val res = typed.fullPredicateJoin(typed2) { name == right.name && city == right.origin } + println(res) + res.columnsCount() shouldBe 8 + res.rowsCount() shouldBe 12 + res.columns().all { it.hasNulls() } shouldBe true + res.select { city and name }.distinct().rowsCount() shouldBe 7 + val distinct = res.select { name and age and city and weight }.distinct() + val expected = typed.append(null, null, null, null) + distinct shouldBe expected + } + + @Test + fun `filter join`() { + val res = typed.filterPredicateJoin(typed2) { city == right.origin } + val expected = typed.innerPredicateJoin(typed2.select { origin }) { city == right.origin }.remove("origin") + res shouldBe expected + } + + @Test + fun `filter not join`() { + val res = typed.excludePredicateJoin(typed2) { city == right.origin } + res.rowsCount() shouldBe 3 + res.city.toSet() shouldBe typed.city.toSet() - typed2.origin.toSet() + + val indexColumn = column("__index__") + val withIndex = typed.addId(indexColumn) + val joined = withIndex.filterPredicateJoin(typed2) { city == right.origin } + val joinedIndices = joined[indexColumn].toSet() + val expected = withIndex.filter { !joinedIndices.contains(it[indexColumn]) }.remove(indexColumn) + + res shouldBe expected + } + + @Test + fun rightJoin() { + val df = dataFrameOf("a", "b")( + 1, "a", + 2, "b", + 3, "c", + ) + + val df1 = dataFrameOf("a", "c")( + 5, "V", + 1, "I", + 2, "II", + 3, "III", + ) + df.append(4, "e").excludeJoin(df1).print() + } + + @Test + fun `test overloads contract`() { + typed.innerPredicateJoin(typed2) { name == right.name && city == right.origin } shouldBe typed.predicateJoin(typed2, JoinType.Inner) { name == right.name && city == right.origin } + typed.leftPredicateJoin(typed2) { name == right.name && city == right.origin } shouldBe typed.predicateJoin(typed2, JoinType.Left) { name == right.name && city == right.origin } + typed.rightPredicateJoin(typed2) { name == right.name && city == right.origin } shouldBe typed.predicateJoin(typed2, JoinType.Right) { name == right.name && city == right.origin } + typed.fullPredicateJoin(typed2) { name == right.name && city == right.origin } shouldBe typed.predicateJoin(typed2, JoinType.Full) { name == right.name && city == right.origin } + typed.excludePredicateJoin(typed2) { city == right.origin } shouldBe typed.predicateJoin(typed2, JoinType.Exclude) { city == right.origin } + typed.filterPredicateJoin(typed2) { city == right.origin } shouldBe typed.predicateJoin(typed2, JoinType.Filter) { city == right.origin } + } +} diff --git a/docs/StardustDocs/d.tree b/docs/StardustDocs/d.tree index 1f81491eff..477809c2df 100644 --- a/docs/StardustDocs/d.tree +++ b/docs/StardustDocs/d.tree @@ -166,6 +166,7 @@ + diff --git a/docs/StardustDocs/topics/multipleDataFrames.md b/docs/StardustDocs/topics/multipleDataFrames.md index 1aa550621f..e9b63b40d5 100644 --- a/docs/StardustDocs/topics/multipleDataFrames.md +++ b/docs/StardustDocs/topics/multipleDataFrames.md @@ -4,3 +4,4 @@ * [`add`](add.md) — union of columns from several [`DataFrames`](DataFrame.md) * [`concat`](concat.md) — union of rows from several [`DataFrames`](DataFrame.md) * [`join`](join.md) — sql-like join of two [`DataFrames`](DataFrame.md) by key columns +* [`predicateJoin`](predicateJoin.md) — join of two [`DataFrames`](DataFrame.md) by an expression that evaluates joined [DataRows](DataRow.md) to Boolean diff --git a/docs/StardustDocs/topics/operations.md b/docs/StardustDocs/topics/operations.md index a8b5f6f539..327743dc55 100644 --- a/docs/StardustDocs/topics/operations.md +++ b/docs/StardustDocs/topics/operations.md @@ -78,6 +78,7 @@ Most multiplex operations end with `into` or `with` function. The following nami * [inferType](inferType.md) — infer column type from column values * [insert](insert.md) — insert column * [join](join.md) — join [`DataFrames`](DataFrame.md) by key columns + * [predicateJoin](predicateJoin.md) — join [`DataFrames`](DataFrame.md) by an expression that evaluates joined [DataRows](DataRow.md) to Boolean * [last](last.md) / [lastOrNull](last.md#lastornull) — find last row by condition * [map](map.md) — map columns into new [`DataFrame`](DataFrame.md) or [`DataColumn`](DataColumn.md) * [max](minmax.md) / [maxBy](minmax.md) / [maxOf](minmax.md) / [maxFor](minmax.md) — max of values diff --git a/docs/StardustDocs/topics/predicateJoin.md b/docs/StardustDocs/topics/predicateJoin.md new file mode 100644 index 0000000000..01edcbe54b --- /dev/null +++ b/docs/StardustDocs/topics/predicateJoin.md @@ -0,0 +1,286 @@ +[//]: # (title: predicateJoin) + + + +Joins two [`DataFrames`](DataFrame.md) by a join expression. + +```kotlin +predicateJoin(otherDf, type = JoinType.Inner) [ { joinExpression } ] + +joinExpression: JoinedDataRow.(JoinedDataRow) -> Boolean + +interface JoinedDataRow: LeftDataRow { + + val right: RightDataRow + +} +``` + +This function is a [join](join.md) variant that lets you match data using any expression that returns Boolean, +which also gives opportunity to compute heuristics that require values from both matching rows. +Can be helpful if data you want to join wasn't designed be relational and requires heuristics to tell if rows are matching, +or has relations other than `equals`. + +For example, you can match rows based on: +* **Order relations** such as `>`, `<`, `in` for numerical or DateTime values +* **Numerical relations** +* **Spatial relations**, like distance within a certain range if your data includes spatial or geographical values +* **String equivalence** using more complex comparison techniques, such as regular expressions, Levenshtein Distance. + +### Join types + +Supported join types: +* `Inner` (default) — only matched rows from left and right [`DataFrames`](DataFrame.md) +* `Filter` — only matched rows from left [`DataFrame`](DataFrame.md) +* `Left` — all rows from left [`DataFrame`](DataFrame.md), mismatches from right [`DataFrame`](DataFrame.md) filled with `null` +* `Right` — all rows from right [`DataFrame`](DataFrame.md), mismatches from left [`DataFrame`](DataFrame.md) filled with `null` +* `Full` — all rows from left and right [`DataFrames`](DataFrame.md), any mismatches filled with `null` +* `Exclude` — only mismatched rows from left + +For every join type there is a shortcut operation: + +#### Inner join + + + + + +```kotlin +campaigns.predicateJoin(visits) { + right.date in startDate..endDate +} +``` + + + + +```kotlin +val date by column() +val startDate by column() +val endDate by column() + +campaigns.predicateJoin(visits) { + right[date] in startDate()..endDate() +} +``` + + + + +```kotlin +campaigns.predicateJoin(visits) { + right[{ "date"() }] in "startDate"().."endDate"() +} +``` + + + + + +#### Filter join + +Special case of inner join when you only need the data from the left table. + + + + + +```kotlin +campaigns.filterPredicateJoin(visits) { + right.date in startDate..endDate +} +``` + + + + +```kotlin +val date by column() +val startDate by column() +val endDate by column() + +campaigns.filterPredicateJoin(visits) { + right[date] in startDate()..endDate() +} +``` + + + + +```kotlin +campaigns.filterPredicateJoin(visits) { + right[{ "date"() }] in "startDate"().."endDate"() +} +``` + + + + + +#### Left join + + + + + +```kotlin +campaigns.leftPredicateJoin(visits) { + right.date in startDate..endDate +} +``` + + + + +```kotlin +val date by column() +val startDate by column() +val endDate by column() + +campaigns.leftPredicateJoin(visits) { + right[date] in startDate()..endDate() +} +``` + + + + +```kotlin +campaigns.leftPredicateJoin(visits) { + right[{ "date"() }] in "startDate"().."endDate"() +} +``` + + + + + +#### Right join + + + + + +```kotlin +campaigns.rightPredicateJoin(visits) { + right.date in startDate..endDate +} +``` + + + + +```kotlin +val date by column() +val startDate by column() +val endDate by column() + +campaigns.rightPredicateJoin(visits) { + right[date] in startDate()..endDate() +} +``` + + + + +```kotlin +campaigns.rightPredicateJoin(visits) { + right[{ "date"() }] in "startDate"().."endDate"() +} +``` + + + + + +#### Full join + + + + + +```kotlin +campaigns.fullPredicateJoin(visits) { + right.date in startDate..endDate +} +``` + + + + +```kotlin +val date by column() +val startDate by column() +val endDate by column() + +campaigns.fullPredicateJoin(visits) { + right[date] in startDate()..endDate() +} +``` + + + + +```kotlin +campaigns.fullPredicateJoin(visits) { + right[{ "date"() }] in "startDate"().."endDate"() +} +``` + + + + + +#### Exclude join + +Can be viewed as **filterJoin** with logically opposite predicate + + + + + +```kotlin +campaigns.excludePredicateJoin(visits) { + right.date in startDate..endDate +} +``` + + + + +```kotlin +val date by column() +val startDate by column() +val endDate by column() + +campaigns.excludePredicateJoin(visits) { + right[date] in startDate()..endDate() +} +``` + + + + +```kotlin +campaigns.excludePredicateJoin(visits) { + right[{ "date"() }] in "startDate"().."endDate"() +} +``` + + + + + +#### Cross join + +Can also be called cross product of two dataframes + + + +```kotlin +campaigns.predicateJoin(visits) { true } +``` + + + + From 983958d85d82ffd505430f36b8f01befdb0c5178 Mon Sep 17 00:00:00 2001 From: Nikita Klimenko Date: Tue, 1 Aug 2023 14:20:04 +0300 Subject: [PATCH 26/45] update snippets due to indentation change in the source code --- ...nx.dataframe.samples.api.Access.byRow.html | 30 +-- ...me.samples.api.Access.columnSelectors.html | 100 ++++----- ...amples.api.Access.columnSelectorsMisc.html | 190 +++++++++--------- ...s.api.Access.columnSelectorsModifySet.html | 70 +++---- ...ples.api.Access.columnSelectorsUsages.html | 70 +++---- ...s.api.Access.columnsSelectorByIndices.html | 30 +-- ...taframe.samples.api.Access.distinctBy.html | 20 +- ...me.samples.api.Access.distinctColumns.html | 20 +- ...dataframe.samples.api.Access.dropLast.html | 20 +- ...x.dataframe.samples.api.Access.dropNA.html | 50 ++--- ...dataframe.samples.api.Access.dropNaNs.html | 50 ++--- ...ataframe.samples.api.Access.dropNulls.html | 50 ++--- ....samples.api.Access.getRowByCondition.html | 50 ++--- ...les.api.Access.getSeveralRowsByRanges.html | 20 +- ...tlinx.dataframe.samples.api.Access.xs.html | 20 +- ...aframe.samples.api.Analyze.columnsFor.html | 50 ++--- ....samples.api.Analyze.countAggregation.html | 30 +-- ...dataframe.samples.api.Analyze.groupBy.html | 40 ++-- ...api.Analyze.groupByDirectAggregations.html | 90 ++++----- ...api.Analyze.groupByWithoutAggregation.html | 30 +-- ....dataframe.samples.api.Analyze.pivot2.html | 20 +- ...les.api.Analyze.pivotAsDataRowOrFrame.html | 20 +- ...s.api.Analyze.pivotCommonAggregations.html | 20 +- ...frame.samples.api.Analyze.pivotCounts.html | 50 ++--- ...rame.samples.api.Analyze.pivotDefault.html | 20 +- ...rame.samples.api.Analyze.pivotGroupBy.html | 20 +- ...rame.samples.api.Analyze.pivotMatches.html | 50 ++--- ...ples.api.Analyze.statisticGroupByMany.html | 20 +- ...es.api.Analyze.statisticGroupBySingle.html | 20 +- ...i.Analyze.statisticGroupBySingleNamed.html | 20 +- ...amples.api.Analyze.statisticPivotMany.html | 20 +- ...pi.Analyze.statisticPivotManySeparate.html | 20 +- ...ples.api.Analyze.statisticPivotSingle.html | 20 +- ...frame.samples.api.Analyze.valueCounts.html | 20 +- ...ame.samples.api.DataRowApi.conditions.html | 30 +-- ...me.samples.api.DataRowApi.expressions.html | 30 +-- ...ataframe.samples.api.Join.joinSpecial.html | 50 ++--- ...aframe.samples.api.Join.joinWithMatch.html | 40 ++-- ...rame.samples.api.Modify.addDataFrames.html | 30 +-- ...aframe.samples.api.Modify.addExisting.html | 20 +- ....dataframe.samples.api.Modify.convert.html | 20 +- ...ataframe.samples.api.Modify.convertTo.html | 40 ++-- ...ataframe.samples.api.Modify.fillNulls.html | 20 +- ...x.dataframe.samples.api.Modify.gather.html | 20 +- ...aframe.samples.api.Modify.gatherNames.html | 20 +- ...nx.dataframe.samples.api.Modify.group.html | 20 +- ...inx.dataframe.samples.api.Modify.move.html | 90 ++++----- ....dataframe.samples.api.Modify.replace.html | 30 +-- ...x.dataframe.samples.api.Modify.sortBy.html | 30 +-- ...nx.dataframe.samples.api.Modify.split.html | 20 +- ...rame.samples.api.Modify.splitIntoRows.html | 20 +- ...taframe.samples.api.Modify.splitRegex.html | 20 +- ...x.dataframe.samples.api.Modify.update.html | 40 ++-- ...rame.samples.api.Modify.updateAsFrame.html | 20 +- 54 files changed, 990 insertions(+), 990 deletions(-) diff --git a/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.Access.byRow.html b/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.Access.byRow.html index 9894ddc3ed..8b3efc9f49 100644 --- a/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.Access.byRow.html +++ b/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.Access.byRow.html @@ -197,9 +197,9 @@ -
- df.df[0].name - +
+ df.df[0].name +
Input DataFrame: rowsCount = 7, columnsCount = 5
@@ -218,11 +218,11 @@

-
-
-
- df.df[3, 5, 6].select { name and age } - +
+
+
+ df.df[3, 5, 6].select { name and age } +
Input DataFrame: rowsCount = 7, columnsCount = 5
@@ -241,11 +241,11 @@

-
-
-
- df.df[3..5] - +
+
+
+ df.df[3..5] +
Input DataFrame: rowsCount = 7, columnsCount = 5
@@ -258,8 +258,8 @@

-
-
+
+
+ \ No newline at end of file diff --git a/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.PredicateJoin.excludePredicateJoin.html b/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.PredicateJoin.excludePredicateJoin.html new file mode 100644 index 0000000000..f1e6ba8965 --- /dev/null +++ b/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.PredicateJoin.excludePredicateJoin.html @@ -0,0 +1,511 @@ + + + + + + +
+ campaigns +
+ +
+
+ visits +
+ +
+
+ result +
+ +
+ + + + \ No newline at end of file diff --git a/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.PredicateJoin.filterPredicateJoin.html b/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.PredicateJoin.filterPredicateJoin.html new file mode 100644 index 0000000000..2b3a05da98 --- /dev/null +++ b/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.PredicateJoin.filterPredicateJoin.html @@ -0,0 +1,511 @@ + + + + + + +
+ campaigns +
+ +
+
+ visits +
+ +
+
+ result +
+ +
+ + + + \ No newline at end of file diff --git a/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.PredicateJoin.fullPredicateJoin.html b/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.PredicateJoin.fullPredicateJoin.html new file mode 100644 index 0000000000..9b58956dee --- /dev/null +++ b/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.PredicateJoin.fullPredicateJoin.html @@ -0,0 +1,513 @@ + + + + + + +
+ campaigns +
+ +
+
+ visits +
+ +
+
+ result +
+ +
+ + + + \ No newline at end of file diff --git a/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.PredicateJoin.leftPredicateJoin.html b/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.PredicateJoin.leftPredicateJoin.html new file mode 100644 index 0000000000..73f6376a12 --- /dev/null +++ b/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.PredicateJoin.leftPredicateJoin.html @@ -0,0 +1,513 @@ + + + + + + +
+ campaigns +
+ +
+
+ visits +
+ +
+
+ result +
+ +
+ + + + \ No newline at end of file diff --git a/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.PredicateJoin.predicateJoin.html b/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.PredicateJoin.predicateJoin.html new file mode 100644 index 0000000000..738dbb9801 --- /dev/null +++ b/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.PredicateJoin.predicateJoin.html @@ -0,0 +1,513 @@ + + + + + + +
+ campaigns +
+ +
+
+ visits +
+ +
+
+ result +
+ +
+ + + + \ No newline at end of file diff --git a/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.PredicateJoin.rightPredicateJoin.html b/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.PredicateJoin.rightPredicateJoin.html new file mode 100644 index 0000000000..6ecdd3b9b2 --- /dev/null +++ b/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.PredicateJoin.rightPredicateJoin.html @@ -0,0 +1,513 @@ + + + + + + +
+ campaigns +
+ +
+
+ visits +
+ +
+
+ result +
+ +
+ + + + \ No newline at end of file diff --git a/docs/StardustDocs/topics/predicateJoin.md b/docs/StardustDocs/topics/predicateJoin.md index 01edcbe54b..c2721708e8 100644 --- a/docs/StardustDocs/topics/predicateJoin.md +++ b/docs/StardustDocs/topics/predicateJoin.md @@ -1,6 +1,6 @@ [//]: # (title: predicateJoin) - + Joins two [`DataFrames`](DataFrame.md) by a join expression. @@ -46,7 +46,7 @@ For every join type there is a shortcut operation: ```kotlin -campaigns.predicateJoin(visits) { +campaigns.innerPredicateJoin(visits) { right.date in startDate..endDate } ``` @@ -59,7 +59,7 @@ val date by column() val startDate by column() val endDate by column() -campaigns.predicateJoin(visits) { +campaigns.innerPredicateJoin(visits) { right[date] in startDate()..endDate() } ``` @@ -68,13 +68,13 @@ campaigns.predicateJoin(visits) { ```kotlin -campaigns.predicateJoin(visits) { +campaigns.innerPredicateJoin(visits) { right[{ "date"() }] in "startDate"().."endDate"() } ``` - + #### Filter join @@ -114,7 +114,7 @@ campaigns.filterPredicateJoin(visits) { ``` - + #### Left join @@ -152,7 +152,7 @@ campaigns.leftPredicateJoin(visits) { ``` - + #### Right join @@ -190,7 +190,7 @@ campaigns.rightPredicateJoin(visits) { ``` - + #### Full join @@ -228,7 +228,7 @@ campaigns.fullPredicateJoin(visits) { ``` - + #### Exclude join @@ -268,7 +268,7 @@ campaigns.excludePredicateJoin(visits) { ``` - + #### Cross join @@ -281,6 +281,6 @@ Can also be called cross product of two dataframes campaigns.predicateJoin(visits) { true } ``` - + From 8bb43c1027ceb1bf8a132de349294577a5f9306a Mon Sep 17 00:00:00 2001 From: Nikita Klimenko Date: Tue, 8 Aug 2023 14:46:03 +0300 Subject: [PATCH 28/45] explain difference between join operations --- .../dataframe/samples/api/PredicateJoin.kt | 218 ++++++- .../dataframe/samples/api/PredicateJoin.kt | 216 ++++++- ...api.PredicateJoin.compareInnerColumns.html | 517 ++++++++++++++++ ....api.PredicateJoin.compareInnerValues.html | 519 ++++++++++++++++ ...samples.api.PredicateJoin.compareLeft.html | 570 ++++++++++++++++++ ...amples.api.PredicateJoin.compareRight.html | 570 ++++++++++++++++++ docs/StardustDocs/topics/predicateJoin.md | 59 +- 7 files changed, 2638 insertions(+), 31 deletions(-) create mode 100644 docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.PredicateJoin.compareInnerColumns.html create mode 100644 docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.PredicateJoin.compareInnerValues.html create mode 100644 docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.PredicateJoin.compareLeft.html create mode 100644 docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.PredicateJoin.compareRight.html diff --git a/core/generated-sources/src/test/kotlin/org/jetbrains/kotlinx/dataframe/samples/api/PredicateJoin.kt b/core/generated-sources/src/test/kotlin/org/jetbrains/kotlinx/dataframe/samples/api/PredicateJoin.kt index 809aa51df6..a28330e546 100644 --- a/core/generated-sources/src/test/kotlin/org/jetbrains/kotlinx/dataframe/samples/api/PredicateJoin.kt +++ b/core/generated-sources/src/test/kotlin/org/jetbrains/kotlinx/dataframe/samples/api/PredicateJoin.kt @@ -19,9 +19,12 @@ import org.jetbrains.kotlinx.dataframe.api.dataFrameOf import org.jetbrains.kotlinx.dataframe.api.excludePredicateJoin import org.jetbrains.kotlinx.dataframe.api.filterPredicateJoin import org.jetbrains.kotlinx.dataframe.api.fullPredicateJoin +import org.jetbrains.kotlinx.dataframe.api.innerJoin import org.jetbrains.kotlinx.dataframe.api.innerPredicateJoin +import org.jetbrains.kotlinx.dataframe.api.leftJoin import org.jetbrains.kotlinx.dataframe.api.leftPredicateJoin import org.jetbrains.kotlinx.dataframe.api.predicateJoin +import org.jetbrains.kotlinx.dataframe.api.rightJoin import org.jetbrains.kotlinx.dataframe.api.rightPredicateJoin import org.jetbrains.kotlinx.dataframe.api.with import org.jetbrains.kotlinx.dataframe.explainer.PluginCallbackProxy @@ -36,7 +39,7 @@ import org.jetbrains.kotlinx.dataframe.jupyter.RenderedContent import org.junit.Test import java.time.format.DateTimeFormatter -class PredicateJoin { +class PredicateJoin : TestBase() { @DataSchema interface Campaigns { @@ -66,7 +69,20 @@ class PredicateJoin { LocalDate(2023, 7, 10), 2, ).cast() - class ColoredValue(val value: T, val backgroundColor: RGBColor, val textColor: RGBColor) + class ColoredValue(val value: T, val backgroundColor: RGBColor, val textColor: RGBColor) { + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as ColoredValue<*> + + return value == other.value + } + + override fun hashCode(): Int { + return value?.hashCode() ?: 0 + } + } private val renderer = object : ChainedCellRenderer(DefaultCellRenderer) { override fun maybeContent(value: Any?, configuration: DisplayConfiguration): RenderedContent? { @@ -131,21 +147,31 @@ class PredicateJoin { "startDate">().value.."endDate">().value } - private fun snippetOutput(coloredResult: DataFrame, result: DataFrame) { - coloredCampaigns.uwrapColoredValues() shouldBe campaigns - coloredVisits.uwrapColoredValues() shouldBe visits - coloredResult.uwrapColoredValues() shouldBe result - - fun DataFrameHtmlData.wrap(title: String): DataFrameHtmlData { - return copy( - body = """ + private fun DataFrameHtmlData.wrap(title: String): DataFrameHtmlData { + return copy( + body = """
$title $body
- """.trimIndent() - ) - } + """.trimIndent() + ) + } + + private fun DataFrameHtmlData.wrap(): DataFrameHtmlData { + return copy( + body = """ +
+ $body +
+ """.trimIndent() + ) + } + + private fun snippetOutput(coloredResult: DataFrame, result: DataFrame) { + coloredCampaigns.uwrapColoredValues() shouldBe campaigns + coloredVisits.uwrapColoredValues() shouldBe visits + coloredResult.uwrapColoredValues() shouldBe result PluginCallbackProxy.overrideHtmlOutput( manualOutput = DataFrameHtmlData.tableDefinitions() @@ -464,4 +490,170 @@ class PredicateJoin { val coloredResult = coloredCampaigns.predicateJoin(coloredVisits) { true } snippetOutput(coloredResult, result) } + + val df1 = dataFrameOf("index", "age", "name")( + 1.spring(), 15.spring(), "BOB".spring(), + 2.summer(), 19.summer(), "ALICE".summer(), + 3.autumn(), 20.autumn(), "CHARLIE".autumn() + ) + + val df2 = dataFrameOf("index", "age", "name")( + 1.spring(), 15.spring(), "Bob".spring(), + 2.summer(), 19.summer(), "Alice".summer(), + 4.winter(), 21.winter(), "John".winter() + ) + + @TransformDataFrameExpressions + @Test + fun compareInnerColumns() { + // SampleStart + df1.innerJoin(df2, "index", "age") + // SampleEnd + + PluginCallbackProxy.overrideHtmlOutput( + manualOutput = DataFrameHtmlData.tableDefinitions() + .plus( + DataFrameHtmlData() + .plus(df1.toColoredHTML().wrap("df1")) + .plus(df2.toColoredHTML().wrap("df2")) + .plus(df1.innerJoin(df2, "index", "age").toColoredHTML().wrap("result")) + .wrapRow() + ) + .plus(other) + ) + } + + @TransformDataFrameExpressions + @Test + fun compareInnerValues() { + // SampleStart + df1.innerPredicateJoin(df2) { it["index"] == right["index"] && it["age"] == right["age"] } + // SampleEnd + + PluginCallbackProxy.overrideHtmlOutput( + manualOutput = DataFrameHtmlData.tableDefinitions() + .plus( + DataFrameHtmlData() + .plus(df1.toColoredHTML().wrap("df1")) + .plus(df2.toColoredHTML().wrap("df2")) + .plus( + df1.innerPredicateJoin(df2) { it["index"] == right["index"] && it["age"] == right["age"] } + .toColoredHTML().wrap("result") + ) + .wrapRow() + ) + .plus(other) + ) + } + + @TransformDataFrameExpressions + @Test + fun compareLeft() { + // SampleStart + df1.leftJoin(df2, "index", "age") + df1.leftPredicateJoin(df2) { it["index"] == right["index"] && it["age"] == right["age"] } + // SampleEnd + + PluginCallbackProxy.overrideHtmlOutput( + manualOutput = DataFrameHtmlData.tableDefinitions() + .plus( + DataFrameHtmlData() + .plus(df1.toColoredHTML().wrap("df1")) + .plus(df2.toColoredHTML().wrap("df2")) + .plus( + df1.leftJoin(df2, "index", "age").toColoredHTML().wrap("result") + ) + .wrapRow() + ) + .plus(DataFrameHtmlData(body = "

")) + .plus( + DataFrameHtmlData() + .plus(df1.toColoredHTML().wrap()) + .plus(df2.toColoredHTML().wrap()) + .plus( + df1.leftPredicateJoin(df2) { it["index"] == right["index"] && it["age"] == right["age"] } + .toColoredHTML().wrap() + ) + .wrapRow() + ) + .plus(other) + ) + } + + @TransformDataFrameExpressions + @Test + fun compareRight() { + // SampleStart + df1.rightJoin(df2, "index", "age") + df1.rightPredicateJoin(df2) { it["index"] == right["index"] && it["age"] == right["age"] } + // SampleEnd + + PluginCallbackProxy.overrideHtmlOutput( + manualOutput = DataFrameHtmlData.tableDefinitions() + .plus( + DataFrameHtmlData() + .plus(df1.toColoredHTML().wrap("df1")) + .plus(df2.toColoredHTML().wrap("df2")) + .plus( + df1.rightJoin(df2, "index", "age").toColoredHTML().wrap("result") + ) + .wrapRow() + ) + .plus(DataFrameHtmlData(body = "

")) + .plus( + DataFrameHtmlData() + .plus(df1.toColoredHTML().wrap()) + .plus(df2.toColoredHTML().wrap()) + .plus( + df1.rightPredicateJoin(df2) { it["index"] == right["index"] && it["age"] == right["age"] } + .toColoredHTML().wrap() + ) + .wrapRow() + ) + .plus(other) + ) + } + + private fun DataFrameHtmlData.wrapRow(): DataFrameHtmlData { + return copy( + body = """ +
+ $body +
+ """.trimIndent() + ) + } + + private val other = DataFrameHtmlData( + style = """ + body { + font-family: "JetBrains Mono", SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace; + font-size: 14px; + } + + :root { + color: #19191C; + background-color: #fff; + } + + :root[theme="dark"] { + background-color: #19191C; + color: #FFFFFFCC + } + + .table-row { + display: flex; + align-items: flex-start; + overflow-x: auto; + } + + .table-container:not(:last-child) { + margin-right: 20px; + } + + td { + white-space: nowrap; + } + """.trimIndent() + ) } diff --git a/core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/samples/api/PredicateJoin.kt b/core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/samples/api/PredicateJoin.kt index bb0d8fcd8f..a28330e546 100644 --- a/core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/samples/api/PredicateJoin.kt +++ b/core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/samples/api/PredicateJoin.kt @@ -19,9 +19,12 @@ import org.jetbrains.kotlinx.dataframe.api.dataFrameOf import org.jetbrains.kotlinx.dataframe.api.excludePredicateJoin import org.jetbrains.kotlinx.dataframe.api.filterPredicateJoin import org.jetbrains.kotlinx.dataframe.api.fullPredicateJoin +import org.jetbrains.kotlinx.dataframe.api.innerJoin import org.jetbrains.kotlinx.dataframe.api.innerPredicateJoin +import org.jetbrains.kotlinx.dataframe.api.leftJoin import org.jetbrains.kotlinx.dataframe.api.leftPredicateJoin import org.jetbrains.kotlinx.dataframe.api.predicateJoin +import org.jetbrains.kotlinx.dataframe.api.rightJoin import org.jetbrains.kotlinx.dataframe.api.rightPredicateJoin import org.jetbrains.kotlinx.dataframe.api.with import org.jetbrains.kotlinx.dataframe.explainer.PluginCallbackProxy @@ -66,7 +69,20 @@ class PredicateJoin : TestBase() { LocalDate(2023, 7, 10), 2, ).cast() - class ColoredValue(val value: T, val backgroundColor: RGBColor, val textColor: RGBColor) + class ColoredValue(val value: T, val backgroundColor: RGBColor, val textColor: RGBColor) { + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as ColoredValue<*> + + return value == other.value + } + + override fun hashCode(): Int { + return value?.hashCode() ?: 0 + } + } private val renderer = object : ChainedCellRenderer(DefaultCellRenderer) { override fun maybeContent(value: Any?, configuration: DisplayConfiguration): RenderedContent? { @@ -131,21 +147,31 @@ class PredicateJoin : TestBase() { "startDate">().value.."endDate">().value } - private fun snippetOutput(coloredResult: DataFrame, result: DataFrame) { - coloredCampaigns.uwrapColoredValues() shouldBe campaigns - coloredVisits.uwrapColoredValues() shouldBe visits - coloredResult.uwrapColoredValues() shouldBe result - - fun DataFrameHtmlData.wrap(title: String): DataFrameHtmlData { - return copy( - body = """ + private fun DataFrameHtmlData.wrap(title: String): DataFrameHtmlData { + return copy( + body = """
$title $body
- """.trimIndent() - ) - } + """.trimIndent() + ) + } + + private fun DataFrameHtmlData.wrap(): DataFrameHtmlData { + return copy( + body = """ +
+ $body +
+ """.trimIndent() + ) + } + + private fun snippetOutput(coloredResult: DataFrame, result: DataFrame) { + coloredCampaigns.uwrapColoredValues() shouldBe campaigns + coloredVisits.uwrapColoredValues() shouldBe visits + coloredResult.uwrapColoredValues() shouldBe result PluginCallbackProxy.overrideHtmlOutput( manualOutput = DataFrameHtmlData.tableDefinitions() @@ -464,4 +490,170 @@ class PredicateJoin : TestBase() { val coloredResult = coloredCampaigns.predicateJoin(coloredVisits) { true } snippetOutput(coloredResult, result) } + + val df1 = dataFrameOf("index", "age", "name")( + 1.spring(), 15.spring(), "BOB".spring(), + 2.summer(), 19.summer(), "ALICE".summer(), + 3.autumn(), 20.autumn(), "CHARLIE".autumn() + ) + + val df2 = dataFrameOf("index", "age", "name")( + 1.spring(), 15.spring(), "Bob".spring(), + 2.summer(), 19.summer(), "Alice".summer(), + 4.winter(), 21.winter(), "John".winter() + ) + + @TransformDataFrameExpressions + @Test + fun compareInnerColumns() { + // SampleStart + df1.innerJoin(df2, "index", "age") + // SampleEnd + + PluginCallbackProxy.overrideHtmlOutput( + manualOutput = DataFrameHtmlData.tableDefinitions() + .plus( + DataFrameHtmlData() + .plus(df1.toColoredHTML().wrap("df1")) + .plus(df2.toColoredHTML().wrap("df2")) + .plus(df1.innerJoin(df2, "index", "age").toColoredHTML().wrap("result")) + .wrapRow() + ) + .plus(other) + ) + } + + @TransformDataFrameExpressions + @Test + fun compareInnerValues() { + // SampleStart + df1.innerPredicateJoin(df2) { it["index"] == right["index"] && it["age"] == right["age"] } + // SampleEnd + + PluginCallbackProxy.overrideHtmlOutput( + manualOutput = DataFrameHtmlData.tableDefinitions() + .plus( + DataFrameHtmlData() + .plus(df1.toColoredHTML().wrap("df1")) + .plus(df2.toColoredHTML().wrap("df2")) + .plus( + df1.innerPredicateJoin(df2) { it["index"] == right["index"] && it["age"] == right["age"] } + .toColoredHTML().wrap("result") + ) + .wrapRow() + ) + .plus(other) + ) + } + + @TransformDataFrameExpressions + @Test + fun compareLeft() { + // SampleStart + df1.leftJoin(df2, "index", "age") + df1.leftPredicateJoin(df2) { it["index"] == right["index"] && it["age"] == right["age"] } + // SampleEnd + + PluginCallbackProxy.overrideHtmlOutput( + manualOutput = DataFrameHtmlData.tableDefinitions() + .plus( + DataFrameHtmlData() + .plus(df1.toColoredHTML().wrap("df1")) + .plus(df2.toColoredHTML().wrap("df2")) + .plus( + df1.leftJoin(df2, "index", "age").toColoredHTML().wrap("result") + ) + .wrapRow() + ) + .plus(DataFrameHtmlData(body = "

")) + .plus( + DataFrameHtmlData() + .plus(df1.toColoredHTML().wrap()) + .plus(df2.toColoredHTML().wrap()) + .plus( + df1.leftPredicateJoin(df2) { it["index"] == right["index"] && it["age"] == right["age"] } + .toColoredHTML().wrap() + ) + .wrapRow() + ) + .plus(other) + ) + } + + @TransformDataFrameExpressions + @Test + fun compareRight() { + // SampleStart + df1.rightJoin(df2, "index", "age") + df1.rightPredicateJoin(df2) { it["index"] == right["index"] && it["age"] == right["age"] } + // SampleEnd + + PluginCallbackProxy.overrideHtmlOutput( + manualOutput = DataFrameHtmlData.tableDefinitions() + .plus( + DataFrameHtmlData() + .plus(df1.toColoredHTML().wrap("df1")) + .plus(df2.toColoredHTML().wrap("df2")) + .plus( + df1.rightJoin(df2, "index", "age").toColoredHTML().wrap("result") + ) + .wrapRow() + ) + .plus(DataFrameHtmlData(body = "

")) + .plus( + DataFrameHtmlData() + .plus(df1.toColoredHTML().wrap()) + .plus(df2.toColoredHTML().wrap()) + .plus( + df1.rightPredicateJoin(df2) { it["index"] == right["index"] && it["age"] == right["age"] } + .toColoredHTML().wrap() + ) + .wrapRow() + ) + .plus(other) + ) + } + + private fun DataFrameHtmlData.wrapRow(): DataFrameHtmlData { + return copy( + body = """ +
+ $body +
+ """.trimIndent() + ) + } + + private val other = DataFrameHtmlData( + style = """ + body { + font-family: "JetBrains Mono", SFMono-Regular, Consolas, "Liberation Mono", Menlo, Courier, monospace; + font-size: 14px; + } + + :root { + color: #19191C; + background-color: #fff; + } + + :root[theme="dark"] { + background-color: #19191C; + color: #FFFFFFCC + } + + .table-row { + display: flex; + align-items: flex-start; + overflow-x: auto; + } + + .table-container:not(:last-child) { + margin-right: 20px; + } + + td { + white-space: nowrap; + } + """.trimIndent() + ) } diff --git a/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.PredicateJoin.compareInnerColumns.html b/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.PredicateJoin.compareInnerColumns.html new file mode 100644 index 0000000000..19380ce514 --- /dev/null +++ b/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.PredicateJoin.compareInnerColumns.html @@ -0,0 +1,517 @@ + + + + + + +
+ +
+ df1 +
+ +
+
+ df2 +
+ +
+
+ result +
+ +
+
+ + + + \ No newline at end of file diff --git a/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.PredicateJoin.compareInnerValues.html b/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.PredicateJoin.compareInnerValues.html new file mode 100644 index 0000000000..a400a558b7 --- /dev/null +++ b/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.PredicateJoin.compareInnerValues.html @@ -0,0 +1,519 @@ + + + + + + +
+ +
+ df1 +
+ +
+
+ df2 +
+ +
+
+ result +
+ +
+
+ + + + \ No newline at end of file diff --git a/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.PredicateJoin.compareLeft.html b/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.PredicateJoin.compareLeft.html new file mode 100644 index 0000000000..8e5675eb0b --- /dev/null +++ b/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.PredicateJoin.compareLeft.html @@ -0,0 +1,570 @@ + + + + + + +
+ +
+ df1 +
+ +
+
+ df2 +
+ +
+
+ result +
+ +
+
+

+
+ +
+
+ +
+
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.PredicateJoin.compareRight.html b/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.PredicateJoin.compareRight.html new file mode 100644 index 0000000000..2da46d6ef4 --- /dev/null +++ b/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.PredicateJoin.compareRight.html @@ -0,0 +1,570 @@ + + + + + + +
+ +
+ df1 +
+ +
+
+ df2 +
+ +
+
+ result +
+ +
+
+

+
+ +
+
+ +
+
+
+ +
+
+
+ +
+
+ + + + \ No newline at end of file diff --git a/docs/StardustDocs/topics/predicateJoin.md b/docs/StardustDocs/topics/predicateJoin.md index c2721708e8..8a314f8813 100644 --- a/docs/StardustDocs/topics/predicateJoin.md +++ b/docs/StardustDocs/topics/predicateJoin.md @@ -5,7 +5,7 @@ Joins two [`DataFrames`](DataFrame.md) by a join expression. ```kotlin -predicateJoin(otherDf, type = JoinType.Inner) [ { joinExpression } ] +predicateJoin(otherDf, type = JoinType.Inner) { joinExpression } joinExpression: JoinedDataRow.(JoinedDataRow) -> Boolean @@ -17,17 +17,16 @@ interface JoinedDataRow: LeftDataRow { ``` This function is a [join](join.md) variant that lets you match data using any expression that returns Boolean, -which also gives opportunity to compute heuristics that require values from both matching rows. -Can be helpful if data you want to join wasn't designed be relational and requires heuristics to tell if rows are matching, +which also gives opportunity to perform operations that require values from both matching rows. +Can be helpful if data you want to join wasn't designed relational and requires heuristics to tell if rows are matching, or has relations other than `equals`. For example, you can match rows based on: * **Order relations** such as `>`, `<`, `in` for numerical or DateTime values -* **Numerical relations** * **Spatial relations**, like distance within a certain range if your data includes spatial or geographical values -* **String equivalence** using more complex comparison techniques, such as regular expressions, Levenshtein Distance. +* **String equivalence** using more complex comparison techniques, such as `contains`, regular expressions, Levenshtein Distance or language models. -### Join types +### Join types with examples Supported join types: * `Inner` (default) — only matched rows from left and right [`DataFrames`](DataFrame.md) @@ -284,3 +283,51 @@ campaigns.predicateJoin(visits) { true } +### Difference from join + +[join](join.md) tries to take advantage of knowledge that data in matching columns is the same (because `equals` is used) to minimize number of columns in the resulting dataframe. + + + +```kotlin +df1.innerJoin(df2, "index", "age") +``` + + + + +Columns that were used in the condition: `index`, `age` - are present only once. Numerical suffix is used to disambiguate columns that are not used in the condition. +Compare it to an equivalent predicate join: + + + +```kotlin +df1.innerPredicateJoin(df2) { it["index"] == right["index"] && it["age"] == right["age"] } +``` + + + + +Here columns from both dataframes are presented as is. So [join](join.md) is better suited for `equals` relation, and predicateJoin is for everything else. +Below are two more examples with join types that allow mismatches. Note the difference in `null` values + + + +```kotlin +df1.leftJoin(df2, "index", "age") +df1.leftPredicateJoin(df2) { it["index"] == right["index"] && it["age"] == right["age"] } +``` + + + + + + +```kotlin +df1.rightJoin(df2, "index", "age") +df1.rightPredicateJoin(df2) { it["index"] == right["index"] && it["age"] == right["age"] } +``` + + + + From 7a41f9399f5cdc3bd42d72cbf3ceafd42774636b Mon Sep 17 00:00:00 2001 From: Jolan Rensen Date: Tue, 8 Aug 2023 17:31:30 +0200 Subject: [PATCH 29/45] updating docs processor to 0.2.3 and updating deprecated @tags --- core/build.gradle.kts | 5 +- .../dataframe/api/ColumnsSelectionDsl.kt | 34 +-- .../jetbrains/kotlinx/dataframe/api/update.kt | 6 +- .../documentation/DocumentationUrls.kt | 2 +- .../documentation/ExpressionsGivenColumn.kt | 2 +- .../ExpressionsGivenDataFrame.kt | 2 +- .../documentation/ExpressionsGivenRow.kt | 2 +- .../ExpressionsGivenRowAndColumn.kt | 2 +- .../documentation/SelectingColumns.kt | 2 +- .../dataframe/documentation/SelectingRows.kt | 4 +- .../dataframe/api/ColumnsSelectionDsl.kt | 214 +++++++++--------- .../jetbrains/kotlinx/dataframe/api/Nulls.kt | 18 +- .../jetbrains/kotlinx/dataframe/api/update.kt | 48 ++-- .../documentation/DocumentationUrls.kt | 42 ++-- .../documentation/ExpressionsGivenColumn.kt | 8 +- .../ExpressionsGivenDataFrame.kt | 2 +- .../documentation/ExpressionsGivenRow.kt | 12 +- .../ExpressionsGivenRowAndColumn.kt | 6 +- .../documentation/SelectingColumns.kt | 16 +- .../dataframe/documentation/SelectingRows.kt | 14 +- gradle/libs.versions.toml | 2 +- 21 files changed, 223 insertions(+), 220 deletions(-) diff --git a/core/build.gradle.kts b/core/build.gradle.kts index 5b3a57cfb7..c4aa9ee4b1 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -176,12 +176,15 @@ val processKDocsMain by creatingProcessDocTask( processors = listOf( INCLUDE_DOC_PROCESSOR, INCLUDE_FILE_DOC_PROCESSOR, - INCLUDE_ARG_DOC_PROCESSOR, + ARG_DOC_PROCESSOR, COMMENT_DOC_PROCESSOR, SAMPLE_DOC_PROCESSOR, ) + arguments += ARG_DOC_PROCESSOR_LOG_NOT_FOUND to false + task { + group = "KDocs" doLast { // ensure generated sources are added to git addGeneratedSourcesToGit.executeCommand() diff --git a/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/ColumnsSelectionDsl.kt b/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/ColumnsSelectionDsl.kt index 40bbcb8bfc..794b2797cd 100644 --- a/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/ColumnsSelectionDsl.kt +++ b/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/ColumnsSelectionDsl.kt @@ -238,7 +238,7 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum * * #### For example: * - * {@includeArg [Examples]} + * {@getArg [Examples]} * * @param [condition\] The optional [ColumnFilter] condition that the column must adhere to. * @return A [SingleColumn] containing the first column that adheres to the given [condition\]. @@ -327,7 +327,7 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum * * #### For example: * - * {@includeArg [Examples]} + * {@getArg [Examples]} * * @param [condition\] The optional [ColumnFilter] condition that the column must adhere to. * @return A [SingleColumn] containing the last column that adheres to the given [condition\]. @@ -416,7 +416,7 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum * * #### For example: * - * {@includeArg [Examples]} + * {@getArg [Examples]} * * @param [condition\] The optional [ColumnFilter] condition that the column must adhere to. * @return A [SingleColumn] containing the single column that adheres to the given [condition\]. @@ -505,7 +505,7 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum * * #### For example: * - * `df.`[select][DataFrame.select]` { `{@includeArg [CommonSubsetOfColumnsDocs.Example]}` }` + * `df.`[select][DataFrame.select]` { `{@getArg [CommonSubsetOfColumnsDocs.Example]}` }` * * @param [endInclusive\] The last column in the subset. * @receiver The first column in the subset. @@ -717,9 +717,9 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum * * #### For example: * - * `df.`[select][select]` { `[col][col]`({@includeArg [CommonColDocs.Arg]}) }` + * `df.`[select][select]` { `[col][col]`({@getArg [CommonColDocs.Arg]}) }` * - * `df.`[select][select]` { myColGroup.`[col][col]`({@includeArg [CommonColDocs.Arg]}) }` + * `df.`[select][select]` { myColGroup.`[col][col]`({@getArg [CommonColDocs.Arg]}) }` * * @return A [ColumnAccessor] for the column with the given argument. * @see [column\] @@ -1020,9 +1020,9 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum * * #### For example: * - * `df.`[select][select]` { `[colGroup][colGroup]`({@includeArg [CommonColGroupDocs.Arg]}) }` + * `df.`[select][select]` { `[colGroup][colGroup]`({@getArg [CommonColGroupDocs.Arg]}) }` * - * `df.`[select][select]` { myColGroup.`[colGroup][colGroup]`({@includeArg [CommonColGroupDocs.Arg]}) }` + * `df.`[select][select]` { myColGroup.`[colGroup][colGroup]`({@getArg [CommonColGroupDocs.Arg]}) }` * * @return A [ColumnAccessor] for the column group with the given argument. * @see [columnGroup\] @@ -1327,9 +1327,9 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum * an accessor for a frame column inside a [ColumnGroup]. * * #### For example: - * `df.`[select][select]` { `[frameCol][frameCol]`({@includeArg [CommonFrameColDocs.Arg]}) }` + * `df.`[select][select]` { `[frameCol][frameCol]`({@getArg [CommonFrameColDocs.Arg]}) }` * - * `df.`[select][select]` { myColGroup.`[frameCol][frameCol]`({@includeArg [CommonFrameColDocs.Arg]}) }` + * `df.`[select][select]` { myColGroup.`[frameCol][frameCol]`({@getArg [CommonFrameColDocs.Arg]}) }` * * @return A [ColumnAccessor] for the frame column with the given argument. * @see [frameColumn\] @@ -1636,7 +1636,7 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum * * #### Examples for this overload: * - * {@includeArg [CommonColsDocs.Examples]} + * {@getArg [CommonColsDocs.Examples]} * */ private interface CommonColsDocs { @@ -1664,7 +1664,7 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum * * #### Examples for this overload: * - * {@includeArg [CommonColsDocs.Examples][org.jetbrains.kotlinx.dataframe.api.ColumnsSelectionDsl.CommonColsDocs.Examples]} + * {@getArg [CommonColsDocs.Examples][org.jetbrains.kotlinx.dataframe.api.ColumnsSelectionDsl.CommonColsDocs.Examples]} * * * @param [predicate\] A [ColumnFilter function][ColumnFilter] that takes a [ColumnReference] and returns a [Boolean]. @@ -1695,11 +1695,11 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum * * #### Examples for this overload: * - * {@includeArg [CommonColsDocs.Examples][org.jetbrains.kotlinx.dataframe.api.ColumnsSelectionDsl.CommonColsDocs.Examples]} + * {@getArg [CommonColsDocs.Examples][org.jetbrains.kotlinx.dataframe.api.ColumnsSelectionDsl.CommonColsDocs.Examples]} * * - * @param [firstCol\] A {@includeArg [AccessorType]} that points to a column. - * @param [otherCols\] Optional additional {@includeArg [AccessorType]}s that point to columns. + * @param [firstCol\] A {@getArg [AccessorType]} that points to a column. + * @param [otherCols\] Optional additional {@getArg [AccessorType]}s that point to columns. * @return A [ColumnSet] containing the columns that [firstCol\] and [otherCols\] point to. */ interface Vararg { @@ -3777,7 +3777,7 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum * * #### Examples for this overload: * - * {@includeArg [CommonAllDocs.Examples]} + * {@getArg [CommonAllDocs.Examples]} * * @see [cols\] */ @@ -3940,7 +3940,7 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum * * #### Examples for this overload: * - * {@includeArg [CommonRecursivelyDocs.Examples]} + * {@getArg [CommonRecursivelyDocs.Examples]} * * @param [includeTopLevel\] Whether to include the top-level columns in the result. `true` by default. */ diff --git a/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/update.kt b/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/update.kt index 16d3af4e6b..010d4276e0 100644 --- a/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/update.kt +++ b/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/update.kt @@ -458,7 +458,7 @@ private interface UpdatePerColMap * * For example: * - * `val defaults = {@includeArg [CommonUpdatePerColMapDoc]}` + * `val defaults = {@getArg [CommonUpdatePerColMapDoc]}` * * `df.`[update][update]` { name and age }.`[where][Update.where]` { ... }.`[perCol][perCol]`(defaults)` * @@ -734,11 +734,11 @@ public fun DataFrame.update( update(*headPlusArray(firstCol, cols)).with(expression) /** - * Specific version of [with] that simply sets the value of each selected row to {@includeArg [CommonSpecificWithDocFirstArg]}. + * Specific version of [with] that simply sets the value of each selected row to {@getArg [CommonSpecificWithDocFirstArg]}. * * For example: * - * `df.`[update][update]` { id }.`[where][Update.where]` { it < 0 }.`{@includeArg [CommonSpecificWithDocSecondArg]}` + * `df.`[update][update]` { id }.`[where][Update.where]` { it < 0 }.`{@getArg [CommonSpecificWithDocSecondArg]}` */ private interface CommonSpecificWithDoc diff --git a/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/documentation/DocumentationUrls.kt b/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/documentation/DocumentationUrls.kt index 2227500253..d6e3592290 100644 --- a/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/documentation/DocumentationUrls.kt +++ b/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/documentation/DocumentationUrls.kt @@ -4,7 +4,7 @@ internal interface DocumentationUrls { interface NameArg - /** See {@includeArg [NameArg]} on the documentation website. */ + /** See {@getArg [NameArg]} on the documentation website. */ interface Text /** https://kotlin.github.io/dataframe */ diff --git a/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/documentation/ExpressionsGivenColumn.kt b/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/documentation/ExpressionsGivenColumn.kt index ac95e39c2f..b8f9a5e7a2 100644 --- a/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/documentation/ExpressionsGivenColumn.kt +++ b/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/documentation/ExpressionsGivenColumn.kt @@ -13,7 +13,7 @@ import org.jetbrains.kotlinx.dataframe.ColumnExpression as DfColumnExpression internal interface ExpressionsGivenColumn { /** - * The key for an @arg that will define the operation name for the examples below. + * The key for an @setArg that will define the operation name for the examples below. * Make sure to [alias][your examples]. */ interface OperationArg diff --git a/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/documentation/ExpressionsGivenDataFrame.kt b/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/documentation/ExpressionsGivenDataFrame.kt index ab2995e74b..c2e249195b 100644 --- a/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/documentation/ExpressionsGivenDataFrame.kt +++ b/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/documentation/ExpressionsGivenDataFrame.kt @@ -22,7 +22,7 @@ internal interface ExpressionsGivenDataFrame { * * For example: * - * {@includeArg [OperationArg]}` { `[select][DataFrame.select]` { lastName } }` + * {@getArg [OperationArg]}` { `[select][DataFrame.select]` { lastName } }` */ interface WithExample } diff --git a/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/documentation/ExpressionsGivenRow.kt b/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/documentation/ExpressionsGivenRow.kt index ab7131e39c..aada644ec8 100644 --- a/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/documentation/ExpressionsGivenRow.kt +++ b/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/documentation/ExpressionsGivenRow.kt @@ -32,7 +32,7 @@ import org.jetbrains.kotlinx.dataframe.RowValueExpression as DfRowValueExpressio internal interface ExpressionsGivenRow { /** - * The key for an @arg that will define the operation name for the examples below. + * The key for an @setArg that will define the operation name for the examples below. * Make sure to [alias][your examples]. */ interface OperationArg diff --git a/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/documentation/ExpressionsGivenRowAndColumn.kt b/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/documentation/ExpressionsGivenRowAndColumn.kt index a175729c52..c239ed431d 100644 --- a/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/documentation/ExpressionsGivenRowAndColumn.kt +++ b/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/documentation/ExpressionsGivenRowAndColumn.kt @@ -13,7 +13,7 @@ import org.jetbrains.kotlinx.dataframe.RowColumnExpression as DfRowColumnExpress internal interface ExpressionsGivenRowAndColumn { /** - * The key for an @arg that will define the operation name for the examples below. + * The key for an @setArg that will define the operation name for the examples below. * Make sure to [alias][your examples]. */ interface OperationArg diff --git a/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/documentation/SelectingColumns.kt b/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/documentation/SelectingColumns.kt index 85dc436dca..553290b13e 100644 --- a/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/documentation/SelectingColumns.kt +++ b/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/documentation/SelectingColumns.kt @@ -64,7 +64,7 @@ internal interface SelectingColumnsLink internal interface SelectingColumns { /** - * The key for an @arg that will define the operation name for the examples below. + * The key for an @setArg that will define the operation name for the examples below. * Make sure to [alias][your examples]. */ interface OperationArg diff --git a/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/documentation/SelectingRows.kt b/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/documentation/SelectingRows.kt index 6d65f010a9..ce3c71f6fb 100644 --- a/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/documentation/SelectingRows.kt +++ b/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/documentation/SelectingRows.kt @@ -22,13 +22,13 @@ import org.jetbrains.kotlinx.dataframe.index internal interface SelectingRows { /** - * The key for an @arg that will define the operation name for the examples below. + * The key for an @setArg that will define the operation name for the examples below. * Make sure to [alias][your examples]. */ interface FirstOperationArg /** - * The key for an @arg that will define the operation name for the examples below. + * The key for an @setArg that will define the operation name for the examples below. * Make sure to [alias][your examples]. */ interface SecondOperationArg diff --git a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/ColumnsSelectionDsl.kt b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/ColumnsSelectionDsl.kt index 221d249c63..f40357ebc5 100644 --- a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/ColumnsSelectionDsl.kt +++ b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/ColumnsSelectionDsl.kt @@ -179,7 +179,7 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum * * #### For example: * - * {@includeArg [Examples]} + * {@getArg [Examples]} * * @param [condition\] The optional [ColumnFilter] condition that the column must adhere to. * @return A [SingleColumn] containing the first column that adheres to the given [condition\]. @@ -194,7 +194,7 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum /** * @include [CommonFirstDocs] - * @arg [CommonFirstDocs.Examples] + * @setArg [CommonFirstDocs.Examples] * `df.`[select][select]` { `[colsOf][colsOf]`<`[String][String]`>().`[first][first]` { it.`[name][ColumnReference.name]`().`[startsWith][String.startsWith]`("year") } }` * * `df.`[select][select]` { `[colsOf][colsOf]`<`[Int][Int]`>().`[first][first]`() }` @@ -204,7 +204,7 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum /** * @include [CommonFirstDocs] - * @arg [CommonFirstDocs.Examples] + * @setArg [CommonFirstDocs.Examples] * `df.`[select][select]` { `[first][first]` { it.`[name][ColumnReference.name]`().`[startsWith][String.startsWith]`("year") } }` * * `df.`[select][select]` { myColumnGroup.`[first][first]`() }` @@ -216,7 +216,7 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum /** * @include [CommonFirstDocs] - * @arg [CommonFirstDocs.Examples] + * @setArg [CommonFirstDocs.Examples] * `df.`[select][select]` { "myColumnGroup".`[first][first]` { it.`[name][ColumnReference.name]`().`[startsWith][String.startsWith]`("year") } }` */ public fun String.first(condition: ColumnFilter<*> = { true }): TransformableSingleColumn<*> = @@ -224,7 +224,7 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum /** * @include [CommonFirstDocs] - * @arg [CommonFirstDocs.Examples] + * @setArg [CommonFirstDocs.Examples] * `df.`[select][select]` { Type::myColumnGroup.`[first][first]` { it.`[name][ColumnReference.name]`().`[startsWith][String.startsWith]`("year") } }` */ public fun KProperty<*>.first(condition: ColumnFilter<*> = { true }): TransformableSingleColumn<*> = @@ -236,7 +236,7 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum * * #### For example: * - * {@includeArg [Examples]} + * {@getArg [Examples]} * * @param [condition\] The optional [ColumnFilter] condition that the column must adhere to. * @return A [SingleColumn] containing the last column that adheres to the given [condition\]. @@ -251,7 +251,7 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum /** * @include [CommonLastDocs] - * @arg [CommonLastDocs.Examples] + * @setArg [CommonLastDocs.Examples] * `df.`[select][select]` { `[colsOf][colsOf]`<`[String][String]`>().`[last][last]` { it.`[name][ColumnReference.name]`().`[startsWith][String.startsWith]`("year") } }` * * `df.`[select][select]` { `[colsOf][colsOf]`<`[Int][Int]`>().`[first][last]`() }` @@ -261,7 +261,7 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum /** * @include [CommonLastDocs] - * @arg [CommonLastDocs.Examples] + * @setArg [CommonLastDocs.Examples] * `df.`[select][select]` { `[last][last]` { it.`[name][ColumnReference.name]`().`[startsWith][String.startsWith]`("year") } }` * * `df.`[select][select]` { myColumnGroup.`[last][last]`() }` @@ -273,7 +273,7 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum /** * @include [CommonLastDocs] - * @arg [CommonLastDocs.Examples] + * @setArg [CommonLastDocs.Examples] * `df.`[select][select]` { "myColumnGroup".`[last][last]` { it.`[name][ColumnReference.name]`().`[startsWith][String.startsWith]`("year") } }` */ public fun String.last(condition: ColumnFilter<*> = { true }): TransformableSingleColumn<*> = @@ -281,7 +281,7 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum /** * @include [CommonLastDocs] - * @arg [CommonLastDocs.Examples] + * @setArg [CommonLastDocs.Examples] * `df.`[select][select]` { Type::myColumnGroup.`[last][last]` { it.`[name][ColumnReference.name]`().`[startsWith][String.startsWith]`("year") } }` */ public fun KProperty<*>.last(condition: ColumnFilter<*> = { true }): TransformableSingleColumn<*> = @@ -293,7 +293,7 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum * * #### For example: * - * {@includeArg [Examples]} + * {@getArg [Examples]} * * @param [condition\] The optional [ColumnFilter] condition that the column must adhere to. * @return A [SingleColumn] containing the single column that adheres to the given [condition\]. @@ -308,7 +308,7 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum /** * @include [CommonSingleDocs] - * @arg [CommonSingleDocs.Examples] + * @setArg [CommonSingleDocs.Examples] * `df.`[select][select]` { `[colsOf][colsOf]`<`[String][String]`>().`[single][single]` { it.`[name][ColumnReference.name]`().`[startsWith][String.startsWith]`("year") } }` * * `df.`[select][select]` { `[colsOf][colsOf]`<`[Int][Int]`>().`[single][single]`() }` @@ -318,7 +318,7 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum /** * @include [CommonSingleDocs] - * @arg [CommonSingleDocs.Examples] + * @setArg [CommonSingleDocs.Examples] * `df.`[select][select]` { `[single][single]` { it.`[name][ColumnReference.name]`().`[startsWith][String.startsWith]`("year") } }` * * `df.`[select][select]` { myColumnGroup.`[single][single]`() }` @@ -330,7 +330,7 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum /** * @include [CommonSingleDocs] - * @arg [CommonSingleDocs.Examples] + * @setArg [CommonSingleDocs.Examples] * `df.`[select][select]` { "myColumnGroup".`[single][single]` { it.`[name][ColumnReference.name]`().`[startsWith][String.startsWith]`("year") } }` */ public fun String.single(condition: ColumnFilter<*> = { true }): TransformableSingleColumn<*> = @@ -338,7 +338,7 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum /** * @include [CommonSingleDocs] - * @arg [CommonSingleDocs.Examples] + * @setArg [CommonSingleDocs.Examples] * `df.`[select][select]` { Type::myColumnGroup.`[single][single]` { it.`[name][ColumnReference.name]`().`[startsWith][String.startsWith]`("year") } }` */ public fun KProperty<*>.single(condition: ColumnFilter<*> = { true }): TransformableSingleColumn<*> = @@ -350,7 +350,7 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum * * #### For example: * - * `df.`[select][DataFrame.select]` { `{@includeArg [CommonSubsetOfColumnsDocs.Example]}` }` + * `df.`[select][DataFrame.select]` { `{@getArg [CommonSubsetOfColumnsDocs.Example]}` }` * * @param [endInclusive\] The last column in the subset. * @receiver The first column in the subset. @@ -365,63 +365,63 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum /** * @include [CommonSubsetOfColumnsDocs] - * {@arg [CommonSubsetOfColumnsDocs.Example] "fromColumn".."toColumn"} + * {@setArg [CommonSubsetOfColumnsDocs.Example] "fromColumn".."toColumn"} */ public operator fun String.rangeTo(endInclusive: String): ColumnSet<*> = toColumnAccessor().rangeTo(endInclusive.toColumnAccessor()) /** * @include [CommonSubsetOfColumnsDocs] - * {@arg [CommonSubsetOfColumnsDocs.Example] "fromColumn"..Type::toColumn} + * {@setArg [CommonSubsetOfColumnsDocs.Example] "fromColumn"..Type::toColumn} */ public operator fun String.rangeTo(endInclusive: KProperty<*>): ColumnSet<*> = toColumnAccessor().rangeTo(endInclusive.toColumnAccessor()) /** * @include [CommonSubsetOfColumnsDocs] - * {@arg [CommonSubsetOfColumnsDocs.Example] "fromColumn"..toColumn} + * {@setArg [CommonSubsetOfColumnsDocs.Example] "fromColumn"..toColumn} */ public operator fun String.rangeTo(endInclusive: AnyColumnReference): ColumnSet<*> = toColumnAccessor().rangeTo(endInclusive) /** * @include [CommonSubsetOfColumnsDocs] - * {@arg [CommonSubsetOfColumnsDocs.Example] Type::fromColumn.."toColumn"} + * {@setArg [CommonSubsetOfColumnsDocs.Example] Type::fromColumn.."toColumn"} */ public operator fun KProperty<*>.rangeTo(endInclusive: String): ColumnSet<*> = toColumnAccessor().rangeTo(endInclusive.toColumnAccessor()) /** * @include [CommonSubsetOfColumnsDocs] - * {@arg [CommonSubsetOfColumnsDocs.Example] Type::fromColumn..Type::toColumn} + * {@setArg [CommonSubsetOfColumnsDocs.Example] Type::fromColumn..Type::toColumn} */ public operator fun KProperty<*>.rangeTo(endInclusive: KProperty<*>): ColumnSet<*> = toColumnAccessor().rangeTo(endInclusive.toColumnAccessor()) /** * @include [CommonSubsetOfColumnsDocs] - * {@arg [CommonSubsetOfColumnsDocs.Example] Type::fromColumn..toColumn} + * {@setArg [CommonSubsetOfColumnsDocs.Example] Type::fromColumn..toColumn} */ public operator fun KProperty<*>.rangeTo(endInclusive: AnyColumnReference): ColumnSet<*> = toColumnAccessor().rangeTo(endInclusive) /** * @include [CommonSubsetOfColumnsDocs] - * {@arg [CommonSubsetOfColumnsDocs.Example] fromColumn.."toColumn"} + * {@setArg [CommonSubsetOfColumnsDocs.Example] fromColumn.."toColumn"} */ public operator fun AnyColumnReference.rangeTo(endInclusive: String): ColumnSet<*> = rangeTo(endInclusive.toColumnAccessor()) /** * @include [CommonSubsetOfColumnsDocs] - * {@arg [CommonSubsetOfColumnsDocs.Example] fromColumn..Type::toColumn} + * {@setArg [CommonSubsetOfColumnsDocs.Example] fromColumn..Type::toColumn} */ public operator fun AnyColumnReference.rangeTo(endInclusive: KProperty<*>): ColumnSet<*> = rangeTo(endInclusive.toColumnAccessor()) /** * @include [CommonSubsetOfColumnsDocs] - * {@arg [CommonSubsetOfColumnsDocs.Example] fromColumn..toColumn} + * {@setArg [CommonSubsetOfColumnsDocs.Example] fromColumn..toColumn} */ public operator fun AnyColumnReference.rangeTo(endInclusive: AnyColumnReference): ColumnSet<*> = object : ColumnSet { @@ -468,19 +468,19 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum * The function can also be called on [ColumnGroupReferences][ColumnGroupReference] to create * an accessor for a column inside a [ColumnGroup]. * - * {@includeArg [CommonColDocs.Note]} + * {@getArg [CommonColDocs.Note]} * * #### For example: * - * `df.`[select][select]` { `[col][col]`({@includeArg [CommonColDocs.Arg]}) }` + * `df.`[select][select]` { `[col][col]`({@getArg [CommonColDocs.Arg]}) }` * - * `df.`[select][select]` { myColGroup.`[col][col]`({@includeArg [CommonColDocs.Arg]}) }` + * `df.`[select][select]` { myColGroup.`[col][col]`({@getArg [CommonColDocs.Arg]}) }` * * @return A [ColumnAccessor] for the column with the given argument. * @see [column\] * @see [colGroup\] * @see [frameCol\] - * {@arg [CommonColDocs.Note]} + * {@setArg [CommonColDocs.Note]} */ private interface CommonColDocs { @@ -492,7 +492,7 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum } /** - * @include [CommonColDocs] {@arg [CommonColDocs.Arg] "columnName"} + * @include [CommonColDocs] {@setArg [CommonColDocs.Arg] "columnName"} * @param [name] The name of the column. */ @Suppress("INAPPLICABLE_JVM_NAME") @@ -500,15 +500,15 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum public fun col(name: String): ColumnAccessor<*> = column(name) /** - * @include [CommonColDocs] {@arg [CommonColDocs.Arg] "columnName"} + * @include [CommonColDocs] {@setArg [CommonColDocs.Arg] "columnName"} * @param [name] The name of the column. * @param [C] The type of the column. */ public fun col(name: String): ColumnAccessor = column(name) /** - * @include [CommonColDocs] {@arg [CommonColDocs.Arg] "columnGroup"["columnName"]} - * {@arg [CommonColDocs.Note] NOTE: For column paths, this is an identity function and can be removed.} + * @include [CommonColDocs] {@setArg [CommonColDocs.Arg] "columnGroup"["columnName"]} + * {@setArg [CommonColDocs.Note] NOTE: For column paths, this is an identity function and can be removed.} * @param [path] The [ColumnPath] pointing to the column. */ @Suppress("INAPPLICABLE_JVM_NAME") @@ -516,20 +516,20 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum public fun col(path: ColumnPath): ColumnAccessor<*> = column(path) /** - * @include [CommonColDocs] {@arg [CommonColDocs.Arg] "columnGroup"["columnName"]} + * @include [CommonColDocs] {@setArg [CommonColDocs.Arg] "columnGroup"["columnName"]} * @param [path] The [ColumnPath] pointing to the column. * @param [C] The type of the column. */ public fun col(path: ColumnPath): ColumnAccessor = column(path) /** - * @include [CommonColDocs] {@arg [CommonColDocs.Arg] Type::columnName} + * @include [CommonColDocs] {@setArg [CommonColDocs.Arg] Type::columnName} * @param [property] The [KProperty] pointing to the column. */ public fun col(property: KProperty): ColumnAccessor = column(property) /** - * @include [CommonColDocs] {@arg [CommonColDocs.Arg] "columnName"} + * @include [CommonColDocs] {@setArg [CommonColDocs.Arg] "columnName"} * @param [name] The name of the column. * @receiver The [ColumnGroupReference] to get the column from. */ @@ -538,7 +538,7 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum public fun ColumnGroupReference.col(name: String): ColumnAccessor<*> = column(name) /** - * @include [CommonColDocs] {@arg [CommonColDocs.Arg] "columnName"} + * @include [CommonColDocs] {@setArg [CommonColDocs.Arg] "columnName"} * @param [name] The name of the column. * @receiver The [ColumnGroupReference] to get the column from. * @param [C] The type of the column. @@ -546,7 +546,7 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum public fun ColumnGroupReference.col(name: String): ColumnAccessor = column(name) /** - * @include [CommonColDocs] {@arg [CommonColDocs.Arg] "columnGroup"["columnName"]} + * @include [CommonColDocs] {@setArg [CommonColDocs.Arg] "columnGroup"["columnName"]} * @param [path] The [ColumnPath] pointing to the column. * @receiver The [ColumnGroupReference] to get the column from. */ @@ -555,7 +555,7 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum public fun ColumnGroupReference.col(path: ColumnPath): ColumnAccessor<*> = column(path) /** - * @include [CommonColDocs] {@arg [CommonColDocs.Arg] "columnGroup"["columnName"]} + * @include [CommonColDocs] {@setArg [CommonColDocs.Arg] "columnGroup"["columnName"]} * @param [path] The [ColumnPath] pointing to the column. * @receiver The [ColumnGroupReference] to get the column from. * @param [C] The type of the column. @@ -563,7 +563,7 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum public fun ColumnGroupReference.col(path: ColumnPath): ColumnAccessor = column(path) /** - * @include [CommonColDocs] {@arg [CommonColDocs.Arg] Type::columnName} + * @include [CommonColDocs] {@setArg [CommonColDocs.Arg] Type::columnName} * @param [property] The [KProperty] pointing to the column. * @receiver The [ColumnGroupReference] to get the column from. */ @@ -587,9 +587,9 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum * * #### For example: * - * `df.`[select][select]` { `[colGroup][colGroup]`({@includeArg [CommonColGroupDocs.Arg]}) }` + * `df.`[select][select]` { `[colGroup][colGroup]`({@getArg [CommonColGroupDocs.Arg]}) }` * - * `df.`[select][select]` { myColGroup.`[colGroup][colGroup]`({@includeArg [CommonColGroupDocs.Arg]}) }` + * `df.`[select][select]` { myColGroup.`[colGroup][colGroup]`({@getArg [CommonColGroupDocs.Arg]}) }` * * @return A [ColumnAccessor] for the column group with the given argument. * @see [columnGroup\] @@ -606,7 +606,7 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum public fun ColumnsContainer<*>.group(name: String): ColumnGroupReference = name.toColumnOf() /** - * @include [CommonColGroupDocs] {@arg [CommonColGroupDocs.Arg] "columnGroupName"} + * @include [CommonColGroupDocs] {@setArg [CommonColGroupDocs.Arg] "columnGroupName"} * @param [name] The name of the column group. */ @Suppress("INAPPLICABLE_JVM_NAME") @@ -614,14 +614,14 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum public fun colGroup(name: String): ColumnAccessor> = columnGroup(name) /** - * @include [CommonColGroupDocs] {@arg [CommonColGroupDocs.Arg] "columnGroupName"} + * @include [CommonColGroupDocs] {@setArg [CommonColGroupDocs.Arg] "columnGroupName"} * @param [name] The name of the column group. * @param [C] The type of the column group. */ public fun colGroup(name: String): ColumnAccessor> = columnGroup(name) /** - * @include [CommonColGroupDocs] {@arg [CommonColGroupDocs.Arg] "columnGroup"["columnGroupName"]} + * @include [CommonColGroupDocs] {@setArg [CommonColGroupDocs.Arg] "columnGroup"["columnGroupName"]} * @param [path] The [ColumnPath] pointing to the column group. */ @Suppress("INAPPLICABLE_JVM_NAME") @@ -629,14 +629,14 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum public fun colGroup(path: ColumnPath): ColumnAccessor> = columnGroup(path) /** - * @include [CommonColGroupDocs] {@arg [CommonColGroupDocs.Arg] "columnGroup"["columnGroupName"]} + * @include [CommonColGroupDocs] {@setArg [CommonColGroupDocs.Arg] "columnGroup"["columnGroupName"]} * @param [path] The [ColumnPath] pointing to the column group. * @param [C] The type of the column group. */ public fun colGroup(path: ColumnPath): ColumnAccessor> = columnGroup(path) /** - * @include [CommonColGroupDocs] {@arg [CommonColGroupDocs.Arg] Type::columnGroupName} + * @include [CommonColGroupDocs] {@setArg [CommonColGroupDocs.Arg] Type::columnGroupName} * @param [property] The [KProperty] pointing to the column group. */ @Suppress("INAPPLICABLE_JVM_NAME") @@ -644,13 +644,13 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum public fun colGroup(property: KProperty>): ColumnAccessor> = columnGroup(property) /** - * @include [CommonColGroupDocs] {@arg [CommonColGroupDocs.Arg] Type::columnGroupName} + * @include [CommonColGroupDocs] {@setArg [CommonColGroupDocs.Arg] Type::columnGroupName} * @param [property] The [KProperty] pointing to the column group. */ public fun colGroup(property: KProperty): ColumnAccessor> = columnGroup(property) /** - * @include [CommonColGroupDocs] {@arg [CommonColGroupDocs.Arg] "columnGroupName"} + * @include [CommonColGroupDocs] {@setArg [CommonColGroupDocs.Arg] "columnGroupName"} * @param [name] The name of the column group. * @receiver The [ColumnGroupReference] to get the column group from. */ @@ -659,7 +659,7 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum public fun ColumnGroupReference.colGroup(name: String): ColumnAccessor> = columnGroup(name) /** - * @include [CommonColGroupDocs] {@arg [CommonColGroupDocs.Arg] "columnGroupName"} + * @include [CommonColGroupDocs] {@setArg [CommonColGroupDocs.Arg] "columnGroupName"} * @param [name] The name of the column group. * @receiver The [ColumnGroupReference] to get the column group from. * @param [C] The type of the column group. @@ -667,7 +667,7 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum public fun ColumnGroupReference.colGroup(name: String): ColumnAccessor> = columnGroup(name) /** - * @include [CommonColGroupDocs] {@arg [CommonColGroupDocs.Arg] "columnGroup"["columnGroupName"]} + * @include [CommonColGroupDocs] {@setArg [CommonColGroupDocs.Arg] "columnGroup"["columnGroupName"]} * @param [path] The [ColumnPath] pointing to the column group. * @receiver The [ColumnGroupReference] to get the column group from. */ @@ -677,7 +677,7 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum columnGroup(path) /** - * @include [CommonColGroupDocs] {@arg [CommonColGroupDocs.Arg] "columnGroup"["columnGroupName"]} + * @include [CommonColGroupDocs] {@setArg [CommonColGroupDocs.Arg] "columnGroup"["columnGroupName"]} * @param [path] The [ColumnPath] pointing to the column group. * @receiver The [ColumnGroupReference] to get the column group from. * @param [C] The type of the column group. @@ -686,7 +686,7 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum columnGroup(path) /** - * @include [CommonColGroupDocs] {@arg [CommonColGroupDocs.Arg] Type::columnGroupName} + * @include [CommonColGroupDocs] {@setArg [CommonColGroupDocs.Arg] Type::columnGroupName} * @param [property] The [KProperty] pointing to the column group. * @receiver The [ColumnGroupReference] to get the column group from. */ @@ -696,7 +696,7 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum columnGroup(property) /** - * @include [CommonColGroupDocs] {@arg [CommonColGroupDocs.Arg] Type::columnGroupName} + * @include [CommonColGroupDocs] {@setArg [CommonColGroupDocs.Arg] Type::columnGroupName} * @param [property] The [KProperty] pointing to the column group. * @receiver The [ColumnGroupReference] to get the column group from. */ @@ -714,9 +714,9 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum * an accessor for a frame column inside a [ColumnGroup]. * * #### For example: - * `df.`[select][select]` { `[frameCol][frameCol]`({@includeArg [CommonFrameColDocs.Arg]}) }` + * `df.`[select][select]` { `[frameCol][frameCol]`({@getArg [CommonFrameColDocs.Arg]}) }` * - * `df.`[select][select]` { myColGroup.`[frameCol][frameCol]`({@includeArg [CommonFrameColDocs.Arg]}) }` + * `df.`[select][select]` { myColGroup.`[frameCol][frameCol]`({@getArg [CommonFrameColDocs.Arg]}) }` * * @return A [ColumnAccessor] for the frame column with the given argument. * @see [frameColumn\] @@ -730,7 +730,7 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum } /** - * @include [CommonFrameColDocs] {@arg [CommonFrameColDocs.Arg] "columnName"} + * @include [CommonFrameColDocs] {@setArg [CommonFrameColDocs.Arg] "columnName"} * @param [name] The name of the frame column. */ @Suppress("INAPPLICABLE_JVM_NAME") @@ -738,14 +738,14 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum public fun frameCol(name: String): ColumnAccessor> = frameColumn(name) /** - * @include [CommonFrameColDocs] {@arg [CommonFrameColDocs.Arg] "columnName"} + * @include [CommonFrameColDocs] {@setArg [CommonFrameColDocs.Arg] "columnName"} * @param [name] The name of the frame column. * @param [C] The type of the frame column. */ public fun frameCol(name: String): ColumnAccessor> = frameColumn(name) /** - * @include [CommonFrameColDocs] {@arg [CommonFrameColDocs.Arg] "columnGroup"["columnName"]} + * @include [CommonFrameColDocs] {@setArg [CommonFrameColDocs.Arg] "columnGroup"["columnName"]} * @param [path] The [ColumnPath] pointing to the frame column. */ @Suppress("INAPPLICABLE_JVM_NAME") @@ -753,14 +753,14 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum public fun frameCol(path: ColumnPath): ColumnAccessor> = frameColumn(path) /** - * @include [CommonFrameColDocs] {@arg [CommonFrameColDocs.Arg] "columnGroup"["columnName"]} + * @include [CommonFrameColDocs] {@setArg [CommonFrameColDocs.Arg] "columnGroup"["columnName"]} * @param [path] The [ColumnPath] pointing to the frame column. * @param [C] The type of the frame column. */ public fun frameCol(path: ColumnPath): ColumnAccessor> = frameColumn(path) /** - * @include [CommonFrameColDocs] {@arg [CommonFrameColDocs.Arg] Type::columnName} + * @include [CommonFrameColDocs] {@setArg [CommonFrameColDocs.Arg] Type::columnName} * @param [property] The [KProperty] pointing to the frame column. */ @Suppress("INAPPLICABLE_JVM_NAME") @@ -768,13 +768,13 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum public fun frameCol(property: KProperty>): ColumnAccessor> = frameColumn(property) /** - * @include [CommonFrameColDocs] {@arg [CommonFrameColDocs.Arg] Type::columnName} + * @include [CommonFrameColDocs] {@setArg [CommonFrameColDocs.Arg] Type::columnName} * @param [property] The [KProperty] pointing to the frame column. */ public fun frameCol(property: KProperty>): ColumnAccessor> = frameColumn(property) /** - * @include [CommonFrameColDocs] {@arg [CommonFrameColDocs.Arg] "columnName"} + * @include [CommonFrameColDocs] {@setArg [CommonFrameColDocs.Arg] "columnName"} * @param [name] The name of the frame column. * @receiver The [ColumnGroupReference] to get the frame column from. */ @@ -783,7 +783,7 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum public fun ColumnGroupReference.frameCol(name: String): ColumnAccessor> = frameColumn(name) /** - * @include [CommonFrameColDocs] {@arg [CommonFrameColDocs.Arg] "columnName"} + * @include [CommonFrameColDocs] {@setArg [CommonFrameColDocs.Arg] "columnName"} * @param [name] The name of the frame column. * @receiver The [ColumnGroupReference] to get the frame column from. * @param [C] The type of the frame column. @@ -791,7 +791,7 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum public fun ColumnGroupReference.frameCol(name: String): ColumnAccessor> = frameColumn(name) /** - * @include [CommonFrameColDocs] {@arg [CommonFrameColDocs.Arg] "columnGroup"["columnName"]} + * @include [CommonFrameColDocs] {@setArg [CommonFrameColDocs.Arg] "columnGroup"["columnName"]} * @param [path] The [ColumnPath] pointing to the frame column. * @receiver The [ColumnGroupReference] to get the frame column from. */ @@ -801,7 +801,7 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum frameColumn(path) /** - * @include [CommonFrameColDocs] {@arg [CommonFrameColDocs.Arg] "columnGroup"["columnName"]} + * @include [CommonFrameColDocs] {@setArg [CommonFrameColDocs.Arg] "columnGroup"["columnName"]} * @param [path] The [ColumnPath] pointing to the frame column. * @receiver The [ColumnGroupReference] to get the frame column from. * @param [C] The type of the frame column. @@ -810,7 +810,7 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum frameColumn(path) /** - * @include [CommonFrameColDocs] {@arg [CommonFrameColDocs.Arg] Type::columnName} + * @include [CommonFrameColDocs] {@setArg [CommonFrameColDocs.Arg] Type::columnName} * @param [property] The [KProperty] pointing to the frame column. * @receiver The [ColumnGroupReference] to get the frame column from. */ @@ -820,7 +820,7 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum frameColumn(property) /** - * @include [CommonFrameColDocs] {@arg [CommonFrameColDocs.Arg] Type::columnName} + * @include [CommonFrameColDocs] {@setArg [CommonFrameColDocs.Arg] Type::columnName} * @param [property] The [KProperty] pointing to the frame column. * @receiver The [ColumnGroupReference] to get the frame column from. */ @@ -855,7 +855,7 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum * * #### Examples for this overload: * - * {@includeArg [CommonColsDocs.Examples]} + * {@getArg [CommonColsDocs.Examples]} * */ private interface CommonColsDocs { @@ -871,8 +871,8 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum /** * @include [CommonColsDocs] * - * @param [firstCol\] A {@includeArg [AccessorType]} that points to a column. - * @param [otherCols\] Optional additional {@includeArg [AccessorType]}s that point to columns. + * @param [firstCol\] A {@getArg [AccessorType]} that points to a column. + * @param [otherCols\] Optional additional {@getArg [AccessorType]}s that point to columns. * @return A [ColumnSet] containing the columns that [firstCol\] and [otherCols\] point to. */ interface Vararg { @@ -888,7 +888,7 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum /** * @include [CommonColsDocs.Predicate] - * @arg [CommonColsDocs.Examples] + * @setArg [CommonColsDocs.Examples] * * `// although these can be shortened to just the `[colsOf][colsOf]` call` * @@ -917,7 +917,7 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum /** * @include [CommonColsDocs.Predicate] - * @arg [CommonColsDocs.Examples] + * @setArg [CommonColsDocs.Examples] * * `df.`[select][select]` { `[cols][cols]` { "e" `[in\][String.contains\]` it.`[name][ColumnPath.name]`() } }` * @@ -956,7 +956,7 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum /** * @include [CommonColsDocs.Predicate] - * @arg [CommonColsDocs.Examples] + * @setArg [CommonColsDocs.Examples] * * `df.`[select][select]` { "myGroupCol".`[cols][cols]` { "e" `[in\][String.contains\]` it.`[name][ColumnPath.name]`() } }` * @@ -980,7 +980,7 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum /** * @include [CommonColsDocs.Predicate] - * @arg [CommonColsDocs.Examples] + * @setArg [CommonColsDocs.Examples] * * `df.`[select][select]` { Type::columnGroup.`[cols][cols]` { "e" `[in\][String.contains\]` it.`[name][ColumnPath.name]`() } }` * @@ -1009,8 +1009,8 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum // region references /** - * @include [CommonColsDocs.Vararg] {@arg [CommonColsDocs.Vararg.AccessorType] [ColumnReference]} - * @arg [CommonColsDocs.Examples] + * @include [CommonColsDocs.Vararg] {@setArg [CommonColsDocs.Vararg.AccessorType] [ColumnReference]} + * @setArg [CommonColsDocs.Examples] * * `df.`[select][select]` { `[colsOf][colsOf]`<`[String][String]`>().`[cols][cols]`(columnA, columnB) }` * @@ -1038,8 +1038,8 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum ): ColumnSet = cols(firstCol, *otherCols) /** - * @include [CommonColsDocs.Vararg] {@arg [CommonColsDocs.Vararg.AccessorType] [ColumnReference]} - * @arg [CommonColsDocs.Examples] + * @include [CommonColsDocs.Vararg] {@setArg [CommonColsDocs.Vararg.AccessorType] [ColumnReference]} + * @setArg [CommonColsDocs.Examples] * * `df.`[select][select]` { `[cols][cols]`(columnA, columnB) }` * @@ -1081,8 +1081,8 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum ): ColumnSet = cols(firstCol, *otherCols) /** - * @include [CommonColsDocs.Vararg] {@arg [CommonColsDocs.Vararg.AccessorType] [ColumnReference]} - * @arg [CommonColsDocs.Examples] + * @include [CommonColsDocs.Vararg] {@setArg [CommonColsDocs.Vararg.AccessorType] [ColumnReference]} + * @setArg [CommonColsDocs.Examples] * * `df.`[select][select]` { "myColumnGroup".`[cols][cols]`(columnA, columnB) }` * @@ -1105,8 +1105,8 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum ): ColumnSet = cols(firstCol, *otherCols) /** - * @include [CommonColsDocs.Vararg] {@arg [CommonColsDocs.Vararg.AccessorType] [ColumnReference]} - * @arg [CommonColsDocs.Examples] + * @include [CommonColsDocs.Vararg] {@setArg [CommonColsDocs.Vararg.AccessorType] [ColumnReference]} + * @setArg [CommonColsDocs.Examples] * * `df.`[select][select]` { Type::myColumnGroup.`[cols][cols]`(columnA, columnB) }` * @@ -1133,8 +1133,8 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum // region names /** - * @include [CommonColsDocs.Vararg] {@arg [CommonColsDocs.Vararg.AccessorType] [String]} - * @arg [CommonColsDocs.Examples] + * @include [CommonColsDocs.Vararg] {@setArg [CommonColsDocs.Vararg.AccessorType] [String]} + * @setArg [CommonColsDocs.Examples] * * `df.`[select][select]` { `[colsOf][colsOf]`<`[String][String]`>().`[cols][cols]`("columnA", "columnB") }` * @@ -1159,8 +1159,8 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum ): ColumnSet = cols(firstCol, *otherCols) /** - * @include [CommonColsDocs.Vararg] {@arg [CommonColsDocs.Vararg.AccessorType] [String]} - * @arg [CommonColsDocs.Examples] + * @include [CommonColsDocs.Vararg] {@setArg [CommonColsDocs.Vararg.AccessorType] [String]} + * @setArg [CommonColsDocs.Examples] * * `df.`[select][select]` { `[cols][cols]`("columnA", "columnB") }` * @@ -1196,8 +1196,8 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum ): ColumnSet<*> = cols(firstCol, *otherCols) /** - * @include [CommonColsDocs.Vararg] {@arg [CommonColsDocs.Vararg.AccessorType] [String]} - * @arg [CommonColsDocs.Examples] + * @include [CommonColsDocs.Vararg] {@setArg [CommonColsDocs.Vararg.AccessorType] [String]} + * @setArg [CommonColsDocs.Examples] * * `df.`[select][select]` { "columnGroup".`[cols][cols]`("columnA", "columnB") }` * @@ -1218,8 +1218,8 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum ): ColumnSet<*> = cols(firstCol, *otherCols) /** - * @include [CommonColsDocs.Vararg] {@arg [CommonColsDocs.Vararg.AccessorType] [String]} - * @arg [CommonColsDocs.Examples] + * @include [CommonColsDocs.Vararg] {@setArg [CommonColsDocs.Vararg.AccessorType] [String]} + * @setArg [CommonColsDocs.Examples] * * `df.`[select][select]` { Type::myColumnGroup.`[cols][cols]`("columnA", "columnB") }` * @@ -1244,8 +1244,8 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum // region properties /** - * @include [CommonColsDocs.Vararg] {@arg [CommonColsDocs.Vararg.AccessorType] [KProperty]} - * @arg [CommonColsDocs.Examples] + * @include [CommonColsDocs.Vararg] {@setArg [CommonColsDocs.Vararg.AccessorType] [KProperty]} + * @setArg [CommonColsDocs.Examples] * * `df.`[select][select]` { `[colsOf][colsOf]`<`[String][String]`>().`[cols][cols]`(Type::colA, Type::colB) }` * @@ -1268,8 +1268,8 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum ): ColumnSet = cols(firstCol, *otherCols) /** - * @include [CommonColsDocs.Vararg] {@arg [CommonColsDocs.Vararg.AccessorType] [KProperty]} - * @arg [CommonColsDocs.Examples] + * @include [CommonColsDocs.Vararg] {@setArg [CommonColsDocs.Vararg.AccessorType] [KProperty]} + * @setArg [CommonColsDocs.Examples] * * `df.`[select][select]` { `[cols][cols]`(Type::colA, Type::colB) }` * @@ -1300,8 +1300,8 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum ): ColumnSet = cols(firstCol, *otherCols) /** - * @include [CommonColsDocs.Vararg] {@arg [CommonColsDocs.Vararg.AccessorType] [KProperty]} - * @arg [CommonColsDocs.Examples] + * @include [CommonColsDocs.Vararg] {@setArg [CommonColsDocs.Vararg.AccessorType] [KProperty]} + * @setArg [CommonColsDocs.Examples] * * `df.`[select][select]` { "myColumnGroup".`[cols][cols]`(Type::colA, Type::colB) }` * @@ -1322,8 +1322,8 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum ): ColumnSet = cols(firstCol, *otherCols) /** - * @include [CommonColsDocs.Vararg] {@arg [CommonColsDocs.Vararg.AccessorType] [KProperty]} - * @arg [CommonColsDocs.Examples] + * @include [CommonColsDocs.Vararg] {@setArg [CommonColsDocs.Vararg.AccessorType] [KProperty]} + * @setArg [CommonColsDocs.Examples] * * `df.`[select][select]` { Type::myColumnGroup.`[cols][cols]`(Type::colA, Type::colB) }` * @@ -1489,7 +1489,7 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum * * #### Examples for this overload: * - * {@includeArg [CommonAllDocs.Examples]} + * {@getArg [CommonAllDocs.Examples]} * * @see [cols\] */ @@ -1501,7 +1501,7 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum /** * @include [CommonAllDocs] - * @arg [CommonAllDocs.Examples] + * @setArg [CommonAllDocs.Examples] * * `df.`[select][select]` { `[cols][cols]` { "a" in `[name][ColumnWithPath.name]` }.`[all][all]`() }` * {@include [LineBreak]} @@ -1512,7 +1512,7 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum /** * @include [CommonAllDocs] - * @arg [CommonAllDocs.Examples] + * @setArg [CommonAllDocs.Examples] * * `df.`[select][select]` { `[all][all]`() }` * @@ -1524,7 +1524,7 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum /** * @include [CommonAllDocs] - * @arg [CommonAllDocs.Examples] + * @setArg [CommonAllDocs.Examples] * * `df.`[select][select]` { "myGroupCol".`[all][all]`() }` */ @@ -1532,7 +1532,7 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum /** * @include [CommonAllDocs] - * @arg [CommonAllDocs.Examples] + * @setArg [CommonAllDocs.Examples] * * `df.`[select][select]` { Type::columnGroup.`[all][all]`() }` */ @@ -1594,7 +1594,7 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum * * #### Examples for this overload: * - * {@includeArg [CommonRecursivelyDocs.Examples]} + * {@getArg [CommonRecursivelyDocs.Examples]} * * @param [includeTopLevel\] Whether to include the top-level columns in the result. `true` by default. */ @@ -1606,7 +1606,7 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum /** * @include [CommonRecursivelyDocs] - * @arg [CommonRecursivelyDocs.Examples] + * @setArg [CommonRecursivelyDocs.Examples] * * `df.`[select][DataFrame.select]` { `[colsOf][ColumnSet.colsOf]`<`[String][String]`>().`[recursively][recursively]`() }` * @@ -1622,7 +1622,7 @@ public interface ColumnsSelectionDsl : ColumnSelectionDsl, SingleColum /** * @include [CommonRecursivelyDocs] - * @arg [CommonRecursivelyDocs.Examples] + * @setArg [CommonRecursivelyDocs.Examples] * * `df.`[select][DataFrame.select]` { `[first][ColumnSet.first]` { col -> col.`[any][DataColumn.any]` { it == "Alice" } }.`[recursively][recursively]`() }` * diff --git a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/Nulls.kt b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/Nulls.kt index 562ab973a4..bf02f92efc 100644 --- a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/Nulls.kt +++ b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/Nulls.kt @@ -23,11 +23,11 @@ import kotlin.reflect.KProperty */ internal interface FillNulls { - /** @include [Update.Usage] {@arg [UpdateOperationArg] [fillNulls][fillNulls]} */ + /** @include [Update.Usage] {@setArg [UpdateOperationArg] [fillNulls][fillNulls]} */ interface Usage } -/** {@arg [SelectingColumns.OperationArg] [fillNulls][fillNulls]} */ +/** {@setArg [SelectingColumns.OperationArg] [fillNulls][fillNulls]} */ private interface SetFillNullsOperationArg /** @@ -119,11 +119,11 @@ internal inline val Float?.isNA: Boolean get() = this == null || this.isNaN() */ internal interface FillNaNs { - /** @include [Update.Usage] {@arg [Update.UpdateOperationArg] [fillNaNs][fillNaNs]} */ + /** @include [Update.Usage] {@setArg [Update.UpdateOperationArg] [fillNaNs][fillNaNs]} */ interface Usage } -/** {@arg [SelectingColumns.OperationArg] [fillNaNs][fillNaNs]} */ +/** {@setArg [SelectingColumns.OperationArg] [fillNaNs][fillNaNs]} */ internal interface SetFillNaNsOperationArg /** @@ -193,11 +193,11 @@ public fun DataFrame.fillNaNs(columns: Iterable>): */ internal interface FillNA { - /** @include [Update.Usage] {@arg [Update.UpdateOperationArg] [fillNA][fillNA]} */ + /** @include [Update.Usage] {@setArg [Update.UpdateOperationArg] [fillNA][fillNA]} */ interface Usage } -/** {@arg [SelectingColumns.OperationArg] [fillNA][fillNA]} */ +/** {@setArg [SelectingColumns.OperationArg] [fillNA][fillNA]} */ internal interface SetFillNAOperationArg /** @@ -288,7 +288,7 @@ internal interface DropNulls { interface WhereAllNullParam } -/** {@arg [SelectingColumns.OperationArg] [dropNulls][dropNulls]} */ +/** {@setArg [SelectingColumns.OperationArg] [dropNulls][dropNulls]} */ private interface SetDropNullsOperationArg /** @@ -395,7 +395,7 @@ internal interface DropNA { interface WhereAllNAParam } -/** {@arg [SelectingColumns.OperationArg] [dropNA][dropNA]} */ +/** {@setArg [SelectingColumns.OperationArg] [dropNA][dropNA]} */ private interface SetDropNAOperationArg /** @@ -502,7 +502,7 @@ internal interface DropNaNs { interface WhereAllNaNParam } -/** {@arg [SelectingColumns.OperationArg] [dropNaNs][dropNaNs]} */ +/** {@setArg [SelectingColumns.OperationArg] [dropNaNs][dropNaNs]} */ private interface SetDropNaNsOperationArg /** diff --git a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/update.kt b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/update.kt index fa4ed2dfeb..57d956fcee 100644 --- a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/update.kt +++ b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/update.kt @@ -42,9 +42,9 @@ public data class Update( internal interface UpdateOperationArg /** - * ## {@includeArg [UpdateOperationArg]} Operation Usage + * ## {@getArg [UpdateOperationArg]} Operation Usage * - * {@includeArg [UpdateOperationArg]} `{ `[columns][SelectingColumns]` }` + * {@getArg [UpdateOperationArg]} `{ `[columns][SelectingColumns]` }` * * - `[.`[where][Update.where]` { `[rowValueCondition][SelectingRows.RowValueCondition.WithExample]` } ]` * @@ -57,7 +57,7 @@ public data class Update( * | .`[withNull][Update.withNull]`() * | .`[withZero][Update.withZero]`() * | .`[asFrame][Update.asFrame]` { `[dataFrameExpression][ExpressionsGivenDataFrame.DataFrameExpression.WithExample]` }` - * {@arg [UpdateOperationArg] [update][update]}{@comment The default name of the `update` operation function name.} + * {@setArg [UpdateOperationArg] [update][update]}{@comment The default name of the `update` operation function name.} */ public interface Usage @@ -79,7 +79,7 @@ public data class Update( // region update -/** {@arg [SelectingColumns.OperationArg] [update][update]} */ +/** {@setArg [SelectingColumns.OperationArg] [update][update]} */ private interface SetSelectingColumnsOperationArg /** @@ -145,8 +145,8 @@ public fun DataFrame.update(columns: Iterable>): Up /** ## Where * @include [SelectingRows.RowValueCondition.WithExample] - * {@arg [SelectingRows.FirstOperationArg] [update][update]} - * {@arg [SelectingRows.SecondOperationArg] [where][where]} + * {@setArg [SelectingRows.FirstOperationArg] [update][update]} + * {@setArg [SelectingRows.SecondOperationArg] [where][where]} * * @param [predicate] The [row value filter][RowValueFilter] to select the rows to update. */ @@ -201,7 +201,7 @@ public fun Update.at(rowRange: IntRange): Update = where { in /** ## Per Row Col * @include [ExpressionsGivenRowAndColumn.RowColumnExpression.WithExample] - * {@arg [ExpressionsGivenRowAndColumn.OperationArg] [update][update]` { age \\\\}.`[perRowCol][perRowCol]} + * {@setArg [ExpressionsGivenRowAndColumn.OperationArg] [update][update]` { age \\\\}.`[perRowCol][perRowCol]} * * ## See Also * - {@include [SeeAlsoWith]} @@ -222,7 +222,7 @@ public typealias UpdateExpression = AddDataRow.(C) -> R /** ## With * {@include [ExpressionsGivenRow.RowValueExpression.WithExample]} - * {@arg [ExpressionsGivenRow.OperationArg] [update][update]` { city \}.`[with][with]} + * {@setArg [ExpressionsGivenRow.OperationArg] [update][update]` { city \}.`[with][with]} * * ## Note * @include [ExpressionsGivenRow.AddDataRowNote] @@ -244,7 +244,7 @@ private interface SeeAlsoWith * Updates selected [column group][ColumnGroup] as a [DataFrame] with the given [expression]. * * {@include [ExpressionsGivenDataFrame.DataFrameExpression.WithExample]} - * {@arg [ExpressionsGivenDataFrame.OperationArg] `df.`[update][update]` { name \}.`[asFrame][asFrame]} + * {@setArg [ExpressionsGivenDataFrame.OperationArg] `df.`[update][update]` { name \}.`[asFrame][asFrame]} * @param [expression] The {@include [ExpressionsGivenDataFrame.DataFrameExpressionLink]} to replace the selected column group with. */ public fun Update>.asFrame(expression: DataFrameExpression>): DataFrame = @@ -280,7 +280,7 @@ private interface UpdatePerColMap * * For example: * - * `val defaults = {@includeArg [CommonUpdatePerColMapDoc]}` + * `val defaults = {@getArg [CommonUpdatePerColMapDoc]}` * * `df.`[update][update]` { name and age }.`[where][Update.where]` { ... }.`[perCol][perCol]`(defaults)` * @@ -290,7 +290,7 @@ private interface CommonUpdatePerColMapDoc /** * @include [CommonUpdatePerColMapDoc] - * {@arg [CommonUpdatePerColMapDoc] `[mapOf][mapOf]`("name" to "Empty", "age" to 0)} + * {@setArg [CommonUpdatePerColMapDoc] `[mapOf][mapOf]`("name" to "Empty", "age" to 0)} * * @param [values] The [Map]<[String], Value> to provide a new value for every selected cell. * For each selected column, there must be a value in the map with the same name. @@ -301,7 +301,7 @@ public fun Update.perCol(values: Map): DataFrame = up /** * {@include [CommonUpdatePerColMapDoc]} - * {@arg [CommonUpdatePerColMapDoc] df.`[getRows][DataFrame.getRows]`(`[listOf][listOf]`(0))` + * {@setArg [CommonUpdatePerColMapDoc] df.`[getRows][DataFrame.getRows]`(`[listOf][listOf]`(0))` * * `.`[update][update]` { name \}.`[with][Update.with]` { "Empty" \}` * @@ -316,7 +316,7 @@ public fun Update.perCol(values: AnyRow): DataFrame = perCol(val /** * @include [CommonUpdatePerColDoc] * @include [ExpressionsGivenColumn.ColumnExpression.WithExample] - * {@arg [ExpressionsGivenColumn.OperationArg] [update][update]` { age \}.`[perCol][perCol]} + * {@setArg [ExpressionsGivenColumn.OperationArg] [update][update]` { age \}.`[perCol][perCol]} * * @param [valueSelector] The {@include [ExpressionsGivenColumn.ColumnExpressionLink]} to provide a new value for every selected cell giving its column. */ @@ -368,7 +368,7 @@ public fun Update.notNull(expression: UpdateExpression): * @include [SelectingColumns.ColumnAccessors] * * {@include [ExpressionsGivenRow.RowValueExpression.WithExample]} - * {@arg [ExpressionsGivenRow.OperationArg] [update][update]`("city")` } + * {@setArg [ExpressionsGivenRow.OperationArg] [update][update]`("city")` } * * @include [Update.ColumnAccessorsParam] * @param [expression] The {@include [ExpressionsGivenRow.RowValueExpressionLink]} to update the rows with. @@ -387,7 +387,7 @@ public fun DataFrame.update( * @include [SelectingColumns.KProperties] * * {@include [ExpressionsGivenRow.RowValueExpression.WithExample]} - * {@arg [ExpressionsGivenRow.OperationArg] [update][update]`("city")` } + * {@setArg [ExpressionsGivenRow.OperationArg] [update][update]`("city")` } * * @include [Update.KPropertiesParam] * @param [expression] The {@include [ExpressionsGivenRow.RowValueExpressionLink]} to update the rows with. @@ -406,7 +406,7 @@ public fun DataFrame.update( * @include [SelectingColumns.ColumnNames] * * {@include [ExpressionsGivenRow.RowValueExpression.WithExample]} - * {@arg [ExpressionsGivenRow.OperationArg] [update][update]`("city")` } + * {@setArg [ExpressionsGivenRow.OperationArg] [update][update]`("city")` } * * @include [Update.ColumnNamesParam] * @param [expression] The {@include [ExpressionsGivenRow.RowValueExpressionLink]} to update the rows with. @@ -419,11 +419,11 @@ public fun DataFrame.update( update(*headPlusArray(firstCol, cols)).with(expression) /** - * Specific version of [with] that simply sets the value of each selected row to {@includeArg [CommonSpecificWithDocFirstArg]}. + * Specific version of [with] that simply sets the value of each selected row to {@getArg [CommonSpecificWithDocFirstArg]}. * * For example: * - * `df.`[update][update]` { id }.`[where][Update.where]` { it < 0 }.`{@includeArg [CommonSpecificWithDocSecondArg]}` + * `df.`[update][update]` { id }.`[where][Update.where]` { it < 0 }.`{@getArg [CommonSpecificWithDocSecondArg]}` */ private interface CommonSpecificWithDoc @@ -436,24 +436,24 @@ private interface CommonSpecificWithDocSecondArg /** * ## With Null * @include [CommonSpecificWithDoc] - * {@arg [CommonSpecificWithDocFirstArg] `null`} - * {@arg [CommonSpecificWithDocSecondArg] [withNull][withNull]`()} + * {@setArg [CommonSpecificWithDocFirstArg] `null`} + * {@setArg [CommonSpecificWithDocSecondArg] [withNull][withNull]`()} */ public fun Update.withNull(): DataFrame = with { null } /** * ## With Zero * @include [CommonSpecificWithDoc] - * {@arg [CommonSpecificWithDocFirstArg] `0`} - * {@arg [CommonSpecificWithDocSecondArg] [withZero][withZero]`()} + * {@setArg [CommonSpecificWithDocFirstArg] `0`} + * {@setArg [CommonSpecificWithDocSecondArg] [withZero][withZero]`()} */ public fun Update.withZero(): DataFrame = updateWithValuePerColumnImpl { 0 as C } /** * ## With Value (Deprecated) * @include [CommonSpecificWithDoc] - * {@arg [CommonSpecificWithDocFirstArg] [value]} - * {@arg [CommonSpecificWithDocSecondArg] [withValue][withValue]`(-1)} + * {@setArg [CommonSpecificWithDocFirstArg] [value]} + * {@setArg [CommonSpecificWithDocSecondArg] [withValue][withValue]`(-1)} * * @param [value] The value to set the selected rows to. In contrast to [with][Update.with], this must be the same exact type. */ diff --git a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/documentation/DocumentationUrls.kt b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/documentation/DocumentationUrls.kt index edca077c6b..428569c630 100644 --- a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/documentation/DocumentationUrls.kt +++ b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/documentation/DocumentationUrls.kt @@ -4,7 +4,7 @@ internal interface DocumentationUrls { interface NameArg - /** See {@includeArg [NameArg]} on the documentation website. */ + /** See {@getArg [NameArg]} on the documentation website. */ interface Text /** https://kotlin.github.io/dataframe */ @@ -12,68 +12,68 @@ internal interface DocumentationUrls { interface DataRow { - /** [{@include [Text]}{@arg [NameArg] Row Expressions}]({@include [Url]}/datarow.html#row-expressions) */ + /** [{@include [Text]}{@setArg [NameArg] Row Expressions}]({@include [Url]}/datarow.html#row-expressions) */ interface RowExpressions - /** [{@include [Text]}{@arg [NameArg] Row Conditions}]({@include [Url]}/datarow.html#row-conditions) */ + /** [{@include [Text]}{@setArg [NameArg] Row Conditions}]({@include [Url]}/datarow.html#row-conditions) */ interface RowConditions } - /** [{@include [Text]}{@arg [NameArg] `NaN` and `NA`}]({@include [Url]}/nanAndNa.html) */ + /** [{@include [Text]}{@setArg [NameArg] `NaN` and `NA`}]({@include [Url]}/nanAndNa.html) */ interface NanAndNa { - /** [{@include [Text]}{@arg [NameArg] `NaN`}]({@include [Url]}/nanAndNa.html#nan) */ + /** [{@include [Text]}{@setArg [NameArg] `NaN`}]({@include [Url]}/nanAndNa.html#nan) */ interface NaN - /** [{@include [Text]}{@arg [NameArg] `NA`}]({@include [Url]}/nanAndNa.html#na) */ + /** [{@include [Text]}{@setArg [NameArg] `NA`}]({@include [Url]}/nanAndNa.html#na) */ interface NA } - /** [{@include [Text]}{@arg [NameArg] `update`}]({@include [Url]}/update.html) */ + /** [{@include [Text]}{@setArg [NameArg] `update`}]({@include [Url]}/update.html) */ interface Update - /** [{@include [Text]}{@arg [NameArg] `fill`}]({@include [Url]}/fill.html) */ + /** [{@include [Text]}{@setArg [NameArg] `fill`}]({@include [Url]}/fill.html) */ interface Fill { - /** [{@include [Text]}{@arg [NameArg] `fillNulls`}]({@include [Url]}/fill.html#fillnulls) */ + /** [{@include [Text]}{@setArg [NameArg] `fillNulls`}]({@include [Url]}/fill.html#fillnulls) */ interface FillNulls - /** [{@include [Text]}{@arg [NameArg] `fillNaNs`}]({@include [Url]}/fill.html#fillnans) */ + /** [{@include [Text]}{@setArg [NameArg] `fillNaNs`}]({@include [Url]}/fill.html#fillnans) */ interface FillNaNs - /** [{@include [Text]}{@arg [NameArg] `fillNA`}]({@include [Url]}/fill.html#fillna) */ + /** [{@include [Text]}{@setArg [NameArg] `fillNA`}]({@include [Url]}/fill.html#fillna) */ interface FillNA } - /** [{@include [Text]}{@arg [NameArg] `drop`}]({@include [Url]}/drop.html) */ + /** [{@include [Text]}{@setArg [NameArg] `drop`}]({@include [Url]}/drop.html) */ interface Drop { - /** [{@include [Text]}{@arg [NameArg] `dropNulls`}]({@include [Url]}/drop.html#dropnulls) */ + /** [{@include [Text]}{@setArg [NameArg] `dropNulls`}]({@include [Url]}/drop.html#dropnulls) */ interface DropNulls - /** [{@include [Text]}{@arg [NameArg] `dropNaNs`}]({@include [Url]}/drop.html#dropnans) */ + /** [{@include [Text]}{@setArg [NameArg] `dropNaNs`}]({@include [Url]}/drop.html#dropnans) */ interface DropNaNs - /** [{@include [Text]}{@arg [NameArg] `dropNA`}]({@include [Url]}/drop.html#dropna) */ + /** [{@include [Text]}{@setArg [NameArg] `dropNA`}]({@include [Url]}/drop.html#dropna) */ interface DropNA } - /** [{@include [Text]}{@arg [NameArg] Access APIs}]({@include [Url]}/apilevels.html) */ + /** [{@include [Text]}{@setArg [NameArg] Access APIs}]({@include [Url]}/apilevels.html) */ interface AccessApis { - /** [{@include [Text]}{@arg [NameArg] String API}]({@include [Url]}/stringapi.html) */ + /** [{@include [Text]}{@setArg [NameArg] String API}]({@include [Url]}/stringapi.html) */ interface StringApi - /** [{@include [Text]}{@arg [NameArg] Column Accessors API}]({@include [Url]}/columnaccessorsapi.html) */ + /** [{@include [Text]}{@setArg [NameArg] Column Accessors API}]({@include [Url]}/columnaccessorsapi.html) */ interface ColumnAccessorsApi - /** [{@include [Text]}{@arg [NameArg] KProperties API}]({@include [Url]}/kpropertiesapi.html) */ + /** [{@include [Text]}{@setArg [NameArg] KProperties API}]({@include [Url]}/kpropertiesapi.html) */ interface KPropertiesApi - /** [{@include [Text]}{@arg [NameArg] Extension Properties API}]({@include [Url]}/extensionpropertiesapi.html) */ + /** [{@include [Text]}{@setArg [NameArg] Extension Properties API}]({@include [Url]}/extensionpropertiesapi.html) */ interface ExtensionPropertiesApi } - /** [{@include [Text]}{@arg [NameArg] Column Selectors}]({@include [Url]}/columnselectors.html) */ + /** [{@include [Text]}{@setArg [NameArg] Column Selectors}]({@include [Url]}/columnselectors.html) */ interface ColumnSelectors } diff --git a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/documentation/ExpressionsGivenColumn.kt b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/documentation/ExpressionsGivenColumn.kt index 3a0f611092..c3fa49a553 100644 --- a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/documentation/ExpressionsGivenColumn.kt +++ b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/documentation/ExpressionsGivenColumn.kt @@ -13,12 +13,12 @@ import org.jetbrains.kotlinx.dataframe.ColumnExpression as DfColumnExpression internal interface ExpressionsGivenColumn { /** - * The key for an @arg that will define the operation name for the examples below. + * The key for an @setArg that will define the operation name for the examples below. * Make sure to [alias][your examples]. */ interface OperationArg - /** {@arg [OperationArg] operation} */ + /** {@setArg [OperationArg] operation} */ interface SetDefaultOperationArg /** Provide a new value for every selected cell given its column using a [column expression][DfColumnExpression]. */ @@ -29,9 +29,9 @@ internal interface ExpressionsGivenColumn { * * For example: * - * `df.`{@includeArg [OperationArg]}` { `[mean][DataColumn.mean]`(skipNA = true) }` + * `df.`{@getArg [OperationArg]}` { `[mean][DataColumn.mean]`(skipNA = true) }` * - * `df.`{@includeArg [OperationArg]}` { `[count][DataColumn.count]` { it > 10 } }` + * `df.`{@getArg [OperationArg]}` { `[count][DataColumn.count]` { it > 10 } }` * @include [SetDefaultOperationArg] */ interface WithExample diff --git a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/documentation/ExpressionsGivenDataFrame.kt b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/documentation/ExpressionsGivenDataFrame.kt index eba50e1657..cfdf12dfc2 100644 --- a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/documentation/ExpressionsGivenDataFrame.kt +++ b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/documentation/ExpressionsGivenDataFrame.kt @@ -22,7 +22,7 @@ internal interface ExpressionsGivenDataFrame { * * For example: * - * {@includeArg [OperationArg]}` { `[select][DataFrame.select]` { lastName } }` + * {@getArg [OperationArg]}` { `[select][DataFrame.select]` { lastName } }` */ interface WithExample } diff --git a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/documentation/ExpressionsGivenRow.kt b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/documentation/ExpressionsGivenRow.kt index aa3fa6d010..03cb30bc9f 100644 --- a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/documentation/ExpressionsGivenRow.kt +++ b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/documentation/ExpressionsGivenRow.kt @@ -29,12 +29,12 @@ import org.jetbrains.kotlinx.dataframe.RowValueExpression as DfRowValueExpressio internal interface ExpressionsGivenRow { /** - * The key for an @arg that will define the operation name for the examples below. + * The key for an @setArg that will define the operation name for the examples below. * Make sure to [alias][your examples]. */ interface OperationArg - /** {@arg [OperationArg] operation} */ + /** {@setArg [OperationArg] operation} */ interface SetDefaultOperationArg /** @@ -53,9 +53,9 @@ internal interface ExpressionsGivenRow { * * For example: * - * `df.`{@includeArg [OperationArg]}` { name.firstName + " " + name.lastName }` + * `df.`{@getArg [OperationArg]}` { name.firstName + " " + name.lastName }` * - * `df.`{@includeArg [OperationArg]}` { 2021 - age }` + * `df.`{@getArg [OperationArg]}` { 2021 - age }` * @include [SetDefaultOperationArg] */ interface WithExample @@ -74,9 +74,9 @@ internal interface ExpressionsGivenRow { * * For example: * - * `df.`{@includeArg [OperationArg]}` { name.firstName + " from " + it }` + * `df.`{@getArg [OperationArg]}` { name.firstName + " from " + it }` * - * `df.`{@includeArg [OperationArg]}` { it.uppercase() }` + * `df.`{@getArg [OperationArg]}` { it.uppercase() }` * {@include [SetDefaultOperationArg]} */ interface WithExample diff --git a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/documentation/ExpressionsGivenRowAndColumn.kt b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/documentation/ExpressionsGivenRowAndColumn.kt index c640597d6c..1fee481a01 100644 --- a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/documentation/ExpressionsGivenRowAndColumn.kt +++ b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/documentation/ExpressionsGivenRowAndColumn.kt @@ -13,12 +13,12 @@ import org.jetbrains.kotlinx.dataframe.RowColumnExpression as DfRowColumnExpress internal interface ExpressionsGivenRowAndColumn { /** - * The key for an @arg that will define the operation name for the examples below. + * The key for an @setArg that will define the operation name for the examples below. * Make sure to [alias][your examples]. */ interface OperationArg - /** {@arg [OperationArg] operation} */ + /** {@setArg [OperationArg] operation} */ interface SetDefaultOperationArg /** Provide a new value for every selected cell given both its row and column using a [row-column expression][DfRowColumnExpression]. */ @@ -29,7 +29,7 @@ internal interface ExpressionsGivenRowAndColumn { * * For example: * - * `df.`{@includeArg [OperationArg]}` { row, col ->` + * `df.`{@getArg [OperationArg]}` { row, col ->` * * `row.age / col.`[mean][DataColumn.mean]`(skipNA = true)` * diff --git a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/documentation/SelectingColumns.kt b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/documentation/SelectingColumns.kt index 755ae5e4ee..818c9dec9e 100644 --- a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/documentation/SelectingColumns.kt +++ b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/documentation/SelectingColumns.kt @@ -26,12 +26,12 @@ internal interface SelectingColumnsLink internal interface SelectingColumns { /** - * The key for an @arg that will define the operation name for the examples below. + * The key for an @setArg that will define the operation name for the examples below. * Make sure to [alias][your examples]. */ interface OperationArg - /** {@arg [OperationArg] operation} */ + /** {@setArg [OperationArg] operation} */ interface SetDefaultOperationArg /** Select or express columns using the Column(s) Selection DSL. @@ -47,11 +47,11 @@ internal interface SelectingColumns { * * For example: * - * `df.`{@includeArg [OperationArg]}` { length `[and][ColumnsSelectionDsl.and]` age }` + * `df.`{@getArg [OperationArg]}` { length `[and][ColumnsSelectionDsl.and]` age }` * - * `df.`{@includeArg [OperationArg]}` { `[cols][ColumnsSelectionDsl.cols]`(1..5) }` + * `df.`{@getArg [OperationArg]}` { `[cols][ColumnsSelectionDsl.cols]`(1..5) }` * - * `df.`{@includeArg [OperationArg]}` { `[colsOf][colsOf]`<`[Double][Double]`>() }` + * `df.`{@getArg [OperationArg]}` { `[colsOf][colsOf]`<`[Double][Double]`>() }` * @include [SetDefaultOperationArg] */ interface WithExample @@ -69,7 +69,7 @@ internal interface SelectingColumns { * * For example: * - * `df.`{@includeArg [OperationArg]}`("length", "age")` + * `df.`{@getArg [OperationArg]}`("length", "age")` * @include [SetDefaultOperationArg] */ interface WithExample @@ -91,7 +91,7 @@ internal interface SelectingColumns { * * `val age by `[column][column]`<`[Double][Double]`>()` * - * `df.`{@includeArg [OperationArg]}`(length, age)` + * `df.`{@getArg [OperationArg]}`(length, age)` * @include [SetDefaultOperationArg] */ interface WithExample @@ -110,7 +110,7 @@ internal interface SelectingColumns { * data class Person(val length: Double, val age: Double) * ``` * - * `df.`{@includeArg [OperationArg]}`(Person::length, Person::age)` + * `df.`{@getArg [OperationArg]}`(Person::length, Person::age)` * @include [SetDefaultOperationArg] */ interface WithExample diff --git a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/documentation/SelectingRows.kt b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/documentation/SelectingRows.kt index c560e0966b..daabc164c6 100644 --- a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/documentation/SelectingRows.kt +++ b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/documentation/SelectingRows.kt @@ -22,18 +22,18 @@ import org.jetbrains.kotlinx.dataframe.index internal interface SelectingRows { /** - * The key for an @arg that will define the operation name for the examples below. + * The key for an @setArg that will define the operation name for the examples below. * Make sure to [alias][your examples]. */ interface FirstOperationArg /** - * The key for an @arg that will define the operation name for the examples below. + * The key for an @setArg that will define the operation name for the examples below. * Make sure to [alias][your examples]. */ interface SecondOperationArg - /** {@arg [FirstOperationArg] operation}{@arg [SecondOperationArg] where} */ + /** {@setArg [FirstOperationArg] operation}{@setArg [SecondOperationArg] where} */ interface SetDefaultOperationArg /** [Entire-Row Condition][EntireRowCondition.WithExample] */ @@ -47,9 +47,9 @@ internal interface SelectingRows { * * For example: * - * `df.`{@includeArg [FirstOperationArg]}` { `[index][index]`() % 2 == 0 }` + * `df.`{@getArg [FirstOperationArg]}` { `[index][index]`() % 2 == 0 }` * - * `df.`{@includeArg [FirstOperationArg]}` { `[diff][diff]` { age } == 0 }` + * `df.`{@getArg [FirstOperationArg]}` { `[diff][diff]` { age } == 0 }` * @include [SetDefaultOperationArg] */ interface WithExample @@ -68,9 +68,9 @@ internal interface SelectingRows { * * For example: * - * `df.`{@includeArg [FirstOperationArg]}` { length }.`{@includeArg [SecondOperationArg]}` { it > 10.0 }` + * `df.`{@getArg [FirstOperationArg]}` { length }.`{@getArg [SecondOperationArg]}` { it > 10.0 }` * - * `df.`{@includeArg [FirstOperationArg]}` { `[cols][ColumnsSelectionDsl.cols]`(1..5) }.`{@includeArg [SecondOperationArg]}` { `[index][index]`() > 4 && city != "Paris" }` + * `df.`{@getArg [FirstOperationArg]}` { `[cols][ColumnsSelectionDsl.cols]`(1..5) }.`{@getArg [SecondOperationArg]}` { `[index][index]`() > 4 && city != "Paris" }` * @include [SetDefaultOperationArg] */ interface WithExample diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index e16e645413..8b6b20a85d 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -24,7 +24,7 @@ junit = "4.13.2" kotestAsserions = "4.6.3" jsoup = "1.14.3" arrow = "11.0.0" -docProcessor = "0.2.1" +docProcessor = "0.2.3" simpleGit = "2.0.1" [libraries] From e8483ee0a7b40fc4163ce8eb0de84e05e7c7a40a Mon Sep 17 00:00:00 2001 From: Nikita Klimenko Date: Tue, 8 Aug 2023 21:07:00 +0300 Subject: [PATCH 30/45] refactoring: predicateJoin -> joinWith --- .../kotlinx/dataframe/api/joinWith.kt | 50 ++++++ .../kotlinx/dataframe/api/predicateJoin.kt | 50 ------ .../api/{predicateJoin.kt => joinWith.kt} | 2 +- .../dataframe/samples/api/JoinWith.kt} | 153 +++++++++--------- .../testSets/person/JoinWithTests.kt} | 44 ++--- .../kotlinx/dataframe/api/joinWith.kt | 50 ++++++ .../kotlinx/dataframe/api/predicateJoin.kt | 50 ------ .../api/{predicateJoin.kt => joinWith.kt} | 2 +- .../dataframe/samples/api/JoinWith.kt} | 153 +++++++++--------- .../testSets/person/JoinWithTests.kt} | 44 ++--- docs/StardustDocs/d.tree | 2 +- ...les.api.JoinWith.compareInnerColumns.html} | 0 ...ples.api.JoinWith.compareInnerValues.html} | 0 ...ame.samples.api.JoinWith.compareLeft.html} | 0 ...me.samples.api.JoinWith.compareRight.html} | 0 ...me.samples.api.JoinWith.crossProduct.html} | 0 ...samples.api.JoinWith.excludeJoinWith.html} | 0 ....samples.api.JoinWith.filterJoinWith.html} | 18 +-- ...me.samples.api.JoinWith.fullJoinWith.html} | 0 ...aframe.samples.api.JoinWith.joinWith.html} | 0 ...me.samples.api.JoinWith.leftJoinWith.html} | 0 ...e.samples.api.JoinWith.rightJoinWith.html} | 0 .../topics/{predicateJoin.md => joinWith.md} | 88 +++++----- .../StardustDocs/topics/multipleDataFrames.md | 2 +- docs/StardustDocs/topics/operations.md | 2 +- 25 files changed, 356 insertions(+), 354 deletions(-) create mode 100644 core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/joinWith.kt delete mode 100644 core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/predicateJoin.kt rename core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/api/{predicateJoin.kt => joinWith.kt} (98%) rename core/{src/test/kotlin/org/jetbrains/kotlinx/dataframe/samples/api/PredicateJoin.kt => generated-sources/src/test/kotlin/org/jetbrains/kotlinx/dataframe/samples/api/JoinWith.kt} (77%) rename core/{src/test/kotlin/org/jetbrains/kotlinx/dataframe/testSets/person/PredicateJoinTests.kt => generated-sources/src/test/kotlin/org/jetbrains/kotlinx/dataframe/testSets/person/JoinWithTests.kt} (61%) create mode 100644 core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/joinWith.kt delete mode 100644 core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/predicateJoin.kt rename core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/api/{predicateJoin.kt => joinWith.kt} (98%) rename core/{generated-sources/src/test/kotlin/org/jetbrains/kotlinx/dataframe/samples/api/PredicateJoin.kt => src/test/kotlin/org/jetbrains/kotlinx/dataframe/samples/api/JoinWith.kt} (77%) rename core/{generated-sources/src/test/kotlin/org/jetbrains/kotlinx/dataframe/testSets/person/PredicateJoinTests.kt => src/test/kotlin/org/jetbrains/kotlinx/dataframe/testSets/person/JoinWithTests.kt} (61%) rename docs/StardustDocs/snippets/{org.jetbrains.kotlinx.dataframe.samples.api.PredicateJoin.compareInnerColumns.html => org.jetbrains.kotlinx.dataframe.samples.api.JoinWith.compareInnerColumns.html} (100%) rename docs/StardustDocs/snippets/{org.jetbrains.kotlinx.dataframe.samples.api.PredicateJoin.compareInnerValues.html => org.jetbrains.kotlinx.dataframe.samples.api.JoinWith.compareInnerValues.html} (100%) rename docs/StardustDocs/snippets/{org.jetbrains.kotlinx.dataframe.samples.api.PredicateJoin.compareLeft.html => org.jetbrains.kotlinx.dataframe.samples.api.JoinWith.compareLeft.html} (100%) rename docs/StardustDocs/snippets/{org.jetbrains.kotlinx.dataframe.samples.api.PredicateJoin.compareRight.html => org.jetbrains.kotlinx.dataframe.samples.api.JoinWith.compareRight.html} (100%) rename docs/StardustDocs/snippets/{org.jetbrains.kotlinx.dataframe.samples.api.PredicateJoin.crossProduct.html => org.jetbrains.kotlinx.dataframe.samples.api.JoinWith.crossProduct.html} (100%) rename docs/StardustDocs/snippets/{org.jetbrains.kotlinx.dataframe.samples.api.PredicateJoin.excludePredicateJoin.html => org.jetbrains.kotlinx.dataframe.samples.api.JoinWith.excludeJoinWith.html} (100%) rename docs/StardustDocs/snippets/{org.jetbrains.kotlinx.dataframe.samples.api.PredicateJoin.filterPredicateJoin.html => org.jetbrains.kotlinx.dataframe.samples.api.JoinWith.filterJoinWith.html} (98%) rename docs/StardustDocs/snippets/{org.jetbrains.kotlinx.dataframe.samples.api.PredicateJoin.fullPredicateJoin.html => org.jetbrains.kotlinx.dataframe.samples.api.JoinWith.fullJoinWith.html} (100%) rename docs/StardustDocs/snippets/{org.jetbrains.kotlinx.dataframe.samples.api.PredicateJoin.predicateJoin.html => org.jetbrains.kotlinx.dataframe.samples.api.JoinWith.joinWith.html} (100%) rename docs/StardustDocs/snippets/{org.jetbrains.kotlinx.dataframe.samples.api.PredicateJoin.leftPredicateJoin.html => org.jetbrains.kotlinx.dataframe.samples.api.JoinWith.leftJoinWith.html} (100%) rename docs/StardustDocs/snippets/{org.jetbrains.kotlinx.dataframe.samples.api.PredicateJoin.rightPredicateJoin.html => org.jetbrains.kotlinx.dataframe.samples.api.JoinWith.rightJoinWith.html} (100%) rename docs/StardustDocs/topics/{predicateJoin.md => joinWith.md} (68%) diff --git a/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/joinWith.kt b/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/joinWith.kt new file mode 100644 index 0000000000..b5d4ef8f4c --- /dev/null +++ b/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/joinWith.kt @@ -0,0 +1,50 @@ +package org.jetbrains.kotlinx.dataframe.api + +import org.jetbrains.kotlinx.dataframe.DataFrame +import org.jetbrains.kotlinx.dataframe.DataRow +import org.jetbrains.kotlinx.dataframe.Selector +import org.jetbrains.kotlinx.dataframe.impl.api.joinWithImpl + +public interface JoinedDataRow : DataRow
{ + public val right: DataRow +} + +public typealias JoinExpression = Selector, Boolean> + +public fun DataFrame.joinWith( + right: DataFrame, + type: JoinType = JoinType.Inner, + joinExpression: JoinExpression +): DataFrame { + return joinWithImpl(right, type, addNewColumns = type.addNewColumns, joinExpression) +} + +public fun DataFrame.innerJoinWith( + right: DataFrame, + joinExpression: JoinExpression +): DataFrame = joinWith(right, JoinType.Inner, joinExpression) + +public fun DataFrame.leftJoinWith( + right: DataFrame, + joinExpression: JoinExpression +): DataFrame = joinWith(right, JoinType.Left, joinExpression) + +public fun DataFrame.rightJoinWith( + right: DataFrame, + joinExpression: JoinExpression +): DataFrame = joinWith(right, JoinType.Right, joinExpression) + +public fun DataFrame.fullJoinWith( + right: DataFrame, + joinExpression: JoinExpression +): DataFrame = joinWith(right, JoinType.Full, joinExpression) + +public fun DataFrame.filterJoinWith( + right: DataFrame, + joinExpression: JoinExpression +): DataFrame = joinWithImpl(right, JoinType.Inner, addNewColumns = false, joinExpression) + +public fun DataFrame.excludeJoinWith( + right: DataFrame, + joinExpression: JoinExpression +): DataFrame = joinWithImpl(right, JoinType.Exclude, addNewColumns = false, joinExpression) diff --git a/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/predicateJoin.kt b/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/predicateJoin.kt deleted file mode 100644 index 1ccd42a52f..0000000000 --- a/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/predicateJoin.kt +++ /dev/null @@ -1,50 +0,0 @@ -package org.jetbrains.kotlinx.dataframe.api - -import org.jetbrains.kotlinx.dataframe.DataFrame -import org.jetbrains.kotlinx.dataframe.DataRow -import org.jetbrains.kotlinx.dataframe.Selector -import org.jetbrains.kotlinx.dataframe.impl.api.predicateJoinImpl - -public interface JoinedDataRow : DataRow { - public val right: DataRow -} - -public typealias JoinExpression = Selector, Boolean> - -public fun DataFrame.predicateJoin( - right: DataFrame, - type: JoinType = JoinType.Inner, - joinExpression: JoinExpression -): DataFrame { - return predicateJoinImpl(right, type, addNewColumns = type.addNewColumns, joinExpression) -} - -public fun DataFrame.innerPredicateJoin( - right: DataFrame, - joinExpression: JoinExpression -): DataFrame = predicateJoin(right, JoinType.Inner, joinExpression) - -public fun DataFrame.leftPredicateJoin( - right: DataFrame, - joinExpression: JoinExpression -): DataFrame = predicateJoin(right, JoinType.Left, joinExpression) - -public fun DataFrame.rightPredicateJoin( - right: DataFrame, - joinExpression: JoinExpression -): DataFrame = predicateJoin(right, JoinType.Right, joinExpression) - -public fun DataFrame.fullPredicateJoin( - right: DataFrame, - joinExpression: JoinExpression -): DataFrame = predicateJoin(right, JoinType.Full, joinExpression) - -public fun DataFrame.filterPredicateJoin( - right: DataFrame, - joinExpression: JoinExpression -): DataFrame = predicateJoinImpl(right, JoinType.Inner, addNewColumns = false, joinExpression) - -public fun DataFrame.excludePredicateJoin( - right: DataFrame, - joinExpression: JoinExpression -): DataFrame = predicateJoinImpl(right, JoinType.Exclude, addNewColumns = false, joinExpression) diff --git a/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/api/predicateJoin.kt b/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/api/joinWith.kt similarity index 98% rename from core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/api/predicateJoin.kt rename to core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/api/joinWith.kt index 701a6875ea..306e4678bb 100644 --- a/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/api/predicateJoin.kt +++ b/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/api/joinWith.kt @@ -24,7 +24,7 @@ internal class JoinedDataRowImpl( override val right: DataRow = DataRowImpl(index1, rightOwner) } -internal fun DataFrame.predicateJoinImpl( +internal fun DataFrame.joinWithImpl( right: DataFrame, type: JoinType = JoinType.Inner, addNewColumns: Boolean, diff --git a/core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/samples/api/PredicateJoin.kt b/core/generated-sources/src/test/kotlin/org/jetbrains/kotlinx/dataframe/samples/api/JoinWith.kt similarity index 77% rename from core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/samples/api/PredicateJoin.kt rename to core/generated-sources/src/test/kotlin/org/jetbrains/kotlinx/dataframe/samples/api/JoinWith.kt index a28330e546..b9636e97b0 100644 --- a/core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/samples/api/PredicateJoin.kt +++ b/core/generated-sources/src/test/kotlin/org/jetbrains/kotlinx/dataframe/samples/api/JoinWith.kt @@ -16,16 +16,17 @@ import org.jetbrains.kotlinx.dataframe.api.colsOf import org.jetbrains.kotlinx.dataframe.api.column import org.jetbrains.kotlinx.dataframe.api.convert import org.jetbrains.kotlinx.dataframe.api.dataFrameOf -import org.jetbrains.kotlinx.dataframe.api.excludePredicateJoin -import org.jetbrains.kotlinx.dataframe.api.filterPredicateJoin -import org.jetbrains.kotlinx.dataframe.api.fullPredicateJoin +import org.jetbrains.kotlinx.dataframe.api.excludeJoinWith +import org.jetbrains.kotlinx.dataframe.api.filterJoinWith +import org.jetbrains.kotlinx.dataframe.api.fullJoinWith +import org.jetbrains.kotlinx.dataframe.api.getValue import org.jetbrains.kotlinx.dataframe.api.innerJoin -import org.jetbrains.kotlinx.dataframe.api.innerPredicateJoin +import org.jetbrains.kotlinx.dataframe.api.innerJoinWith +import org.jetbrains.kotlinx.dataframe.api.joinWith import org.jetbrains.kotlinx.dataframe.api.leftJoin -import org.jetbrains.kotlinx.dataframe.api.leftPredicateJoin -import org.jetbrains.kotlinx.dataframe.api.predicateJoin +import org.jetbrains.kotlinx.dataframe.api.leftJoinWith import org.jetbrains.kotlinx.dataframe.api.rightJoin -import org.jetbrains.kotlinx.dataframe.api.rightPredicateJoin +import org.jetbrains.kotlinx.dataframe.api.rightJoinWith import org.jetbrains.kotlinx.dataframe.api.with import org.jetbrains.kotlinx.dataframe.explainer.PluginCallbackProxy import org.jetbrains.kotlinx.dataframe.explainer.TransformDataFrameExpressions @@ -39,7 +40,7 @@ import org.jetbrains.kotlinx.dataframe.jupyter.RenderedContent import org.junit.Test import java.time.format.DateTimeFormatter -class PredicateJoin : TestBase() { +class JoinWith : TestBase() { @DataSchema interface Campaigns { @@ -218,265 +219,265 @@ class PredicateJoin : TestBase() { @TransformDataFrameExpressions @Test - fun predicateJoin_accessors() { + fun joinWith_accessors() { val result = run { // SampleStart val date by column() val startDate by column() val endDate by column() - campaigns.innerPredicateJoin(visits) { + campaigns.innerJoinWith(visits) { right[date] in startDate()..endDate() } // SampleEnd } - val coloredResult = coloredCampaigns.innerPredicateJoin(coloredVisits, joinExpression = joinExpression) + val coloredResult = coloredCampaigns.innerJoinWith(coloredVisits, joinExpression = joinExpression) snippetOutput(coloredResult, result) } @TransformDataFrameExpressions @Test - fun filterPredicateJoin_accessors() { + fun filterJoinWith_accessors() { val result = run { // SampleStart val date by column() val startDate by column() val endDate by column() - campaigns.filterPredicateJoin(visits) { + campaigns.filterJoinWith(visits) { right[date] in startDate()..endDate() } // SampleEnd } - val coloredResult = coloredCampaigns.filterPredicateJoin(coloredVisits, joinExpression = joinExpression) + val coloredResult = coloredCampaigns.filterJoinWith(coloredVisits, joinExpression = joinExpression) snippetOutput(coloredResult, result) } @TransformDataFrameExpressions @Test - fun leftPredicateJoin_accessors() { + fun leftJoinWith_accessors() { val result = run { // SampleStart val date by column() val startDate by column() val endDate by column() - campaigns.leftPredicateJoin(visits) { + campaigns.leftJoinWith(visits) { right[date] in startDate()..endDate() } // SampleEnd } - val coloredResult = coloredCampaigns.leftPredicateJoin(coloredVisits, joinExpression = joinExpression) + val coloredResult = coloredCampaigns.leftJoinWith(coloredVisits, joinExpression = joinExpression) snippetOutput(coloredResult, result) } @TransformDataFrameExpressions @Test - fun rightPredicateJoin_accessors() { + fun rightJoinWith_accessors() { val result = run { // SampleStart val date by column() val startDate by column() val endDate by column() - campaigns.rightPredicateJoin(visits) { + campaigns.rightJoinWith(visits) { right[date] in startDate()..endDate() } // SampleEnd } - val coloredResult = coloredCampaigns.rightPredicateJoin(coloredVisits, joinExpression = joinExpression) + val coloredResult = coloredCampaigns.rightJoinWith(coloredVisits, joinExpression = joinExpression) snippetOutput(coloredResult, result) } @TransformDataFrameExpressions @Test - fun fullPredicateJoin_accessors() { + fun fullJoinWith_accessors() { val result = run { // SampleStart val date by column() val startDate by column() val endDate by column() - campaigns.fullPredicateJoin(visits) { + campaigns.fullJoinWith(visits) { right[date] in startDate()..endDate() } // SampleEnd } - val coloredResult = coloredCampaigns.fullPredicateJoin(coloredVisits, joinExpression = joinExpression) + val coloredResult = coloredCampaigns.fullJoinWith(coloredVisits, joinExpression = joinExpression) snippetOutput(coloredResult, result) } @TransformDataFrameExpressions @Test - fun excludePredicateJoin_accessors() { + fun excludeJoinWith_accessors() { val result = run { // SampleStart val date by column() val startDate by column() val endDate by column() - campaigns.excludePredicateJoin(visits) { + campaigns.excludeJoinWith(visits) { right[date] in startDate()..endDate() } // SampleEnd } - val coloredResult = coloredCampaigns.excludePredicateJoin(coloredVisits, joinExpression = joinExpression) + val coloredResult = coloredCampaigns.excludeJoinWith(coloredVisits, joinExpression = joinExpression) snippetOutput(coloredResult, result) } @TransformDataFrameExpressions @Test - fun predicateJoin_strings() { + fun joinWith_strings() { val result = // SampleStart - campaigns.innerPredicateJoin(visits) { - right[{ "date"() }] in "startDate"().."endDate"() + campaigns.innerJoinWith(visits) { + right.getValue("date") in "startDate"().."endDate"() } // SampleEnd - val coloredResult = coloredCampaigns.innerPredicateJoin(coloredVisits, joinExpression = joinExpression) + val coloredResult = coloredCampaigns.innerJoinWith(coloredVisits, joinExpression = joinExpression) snippetOutput(coloredResult, result) } @TransformDataFrameExpressions @Test - fun filterPredicateJoin_strings() { + fun filterJoinWith_strings() { val result = // SampleStart - campaigns.filterPredicateJoin(visits) { - right[{ "date"() }] in "startDate"().."endDate"() + campaigns.filterJoinWith(visits) { + right.getValue("date") in "startDate"().."endDate"() } // SampleEnd - val coloredResult = coloredCampaigns.filterPredicateJoin(coloredVisits, joinExpression = joinExpression) + val coloredResult = coloredCampaigns.filterJoinWith(coloredVisits, joinExpression = joinExpression) snippetOutput(coloredResult, result) } @TransformDataFrameExpressions @Test - fun leftPredicateJoin_strings() { + fun leftJoinWith_strings() { val result = // SampleStart - campaigns.leftPredicateJoin(visits) { - right[{ "date"() }] in "startDate"().."endDate"() + campaigns.leftJoinWith(visits) { + right.getValue("date") in "startDate"().."endDate"() } // SampleEnd - val coloredResult = coloredCampaigns.leftPredicateJoin(coloredVisits, joinExpression = joinExpression) + val coloredResult = coloredCampaigns.leftJoinWith(coloredVisits, joinExpression = joinExpression) snippetOutput(coloredResult, result) } @TransformDataFrameExpressions @Test - fun rightPredicateJoin_strings() { + fun rightJoinWith_strings() { val result = // SampleStart - campaigns.rightPredicateJoin(visits) { - right[{ "date"() }] in "startDate"().."endDate"() + campaigns.rightJoinWith(visits) { + right.getValue("date") in "startDate"().."endDate"() } // SampleEnd - val coloredResult = coloredCampaigns.rightPredicateJoin(coloredVisits, joinExpression = joinExpression) + val coloredResult = coloredCampaigns.rightJoinWith(coloredVisits, joinExpression = joinExpression) snippetOutput(coloredResult, result) } @TransformDataFrameExpressions @Test - fun fullPredicateJoin_strings() { + fun fullJoinWith_strings() { val result = // SampleStart - campaigns.fullPredicateJoin(visits) { - right[{ "date"() }] in "startDate"().."endDate"() + campaigns.fullJoinWith(visits) { + right.getValue("date") in "startDate"().."endDate"() } // SampleEnd - val coloredResult = coloredCampaigns.fullPredicateJoin(coloredVisits, joinExpression = joinExpression) + val coloredResult = coloredCampaigns.fullJoinWith(coloredVisits, joinExpression = joinExpression) snippetOutput(coloredResult, result) } @TransformDataFrameExpressions @Test - fun excludePredicateJoin_strings() { + fun excludeJoinWith_strings() { val result = // SampleStart - campaigns.excludePredicateJoin(visits) { - right[{ "date"() }] in "startDate"().."endDate"() + campaigns.excludeJoinWith(visits) { + right.getValue("date") in "startDate"().."endDate"() } // SampleEnd - val coloredResult = coloredCampaigns.excludePredicateJoin(coloredVisits, joinExpression = joinExpression) + val coloredResult = coloredCampaigns.excludeJoinWith(coloredVisits, joinExpression = joinExpression) snippetOutput(coloredResult, result) } @TransformDataFrameExpressions @Test - fun predicateJoin_properties() { + fun joinWith_properties() { val result = // SampleStart - campaigns.innerPredicateJoin(visits) { + campaigns.innerJoinWith(visits) { right.date in startDate..endDate } // SampleEnd - val coloredResult = coloredCampaigns.innerPredicateJoin(coloredVisits, joinExpression = joinExpression) + val coloredResult = coloredCampaigns.innerJoinWith(coloredVisits, joinExpression = joinExpression) snippetOutput(coloredResult, result) } @TransformDataFrameExpressions @Test - fun filterPredicateJoin_properties() { + fun filterJoinWith_properties() { val result = // SampleStart - campaigns.filterPredicateJoin(visits) { + campaigns.filterJoinWith(visits) { right.date in startDate..endDate } // SampleEnd - val coloredResult = coloredCampaigns.filterPredicateJoin(coloredVisits, joinExpression = joinExpression) + val coloredResult = coloredCampaigns.filterJoinWith(coloredVisits, joinExpression = joinExpression) snippetOutput(coloredResult, result) } @TransformDataFrameExpressions @Test - fun leftPredicateJoin_properties() { + fun leftJoinWith_properties() { val result = // SampleStart - campaigns.leftPredicateJoin(visits) { + campaigns.leftJoinWith(visits) { right.date in startDate..endDate } // SampleEnd - val coloredResult = coloredCampaigns.leftPredicateJoin(coloredVisits, joinExpression = joinExpression) + val coloredResult = coloredCampaigns.leftJoinWith(coloredVisits, joinExpression = joinExpression) snippetOutput(coloredResult, result) } @TransformDataFrameExpressions @Test - fun rightPredicateJoin_properties() { + fun rightJoinWith_properties() { val result = // SampleStart - campaigns.rightPredicateJoin(visits) { + campaigns.rightJoinWith(visits) { right.date in startDate..endDate } // SampleEnd - val coloredResult = coloredCampaigns.rightPredicateJoin(coloredVisits, joinExpression = joinExpression) + val coloredResult = coloredCampaigns.rightJoinWith(coloredVisits, joinExpression = joinExpression) snippetOutput(coloredResult, result) } @TransformDataFrameExpressions @Test - fun fullPredicateJoin_properties() { + fun fullJoinWith_properties() { val result = // SampleStart - campaigns.fullPredicateJoin(visits) { + campaigns.fullJoinWith(visits) { right.date in startDate..endDate } // SampleEnd - val coloredResult = coloredCampaigns.fullPredicateJoin(coloredVisits, joinExpression = joinExpression) + val coloredResult = coloredCampaigns.fullJoinWith(coloredVisits, joinExpression = joinExpression) snippetOutput(coloredResult, result) } @TransformDataFrameExpressions @Test - fun excludePredicateJoin_properties() { + fun excludeJoinWith_properties() { val result = // SampleStart - campaigns.excludePredicateJoin(visits) { + campaigns.excludeJoinWith(visits) { right.date in startDate..endDate } // SampleEnd - val coloredResult = coloredCampaigns.excludePredicateJoin(coloredVisits, joinExpression = joinExpression) + val coloredResult = coloredCampaigns.excludeJoinWith(coloredVisits, joinExpression = joinExpression) snippetOutput(coloredResult, result) } @@ -485,9 +486,9 @@ class PredicateJoin : TestBase() { fun crossProduct() { val result = // SampleStart - campaigns.predicateJoin(visits) { true } + campaigns.joinWith(visits) { true } // SampleEnd - val coloredResult = coloredCampaigns.predicateJoin(coloredVisits) { true } + val coloredResult = coloredCampaigns.joinWith(coloredVisits) { true } snippetOutput(coloredResult, result) } @@ -527,7 +528,7 @@ class PredicateJoin : TestBase() { @Test fun compareInnerValues() { // SampleStart - df1.innerPredicateJoin(df2) { it["index"] == right["index"] && it["age"] == right["age"] } + df1.innerJoinWith(df2) { it["index"] == right["index"] && it["age"] == right["age"] } // SampleEnd PluginCallbackProxy.overrideHtmlOutput( @@ -537,7 +538,7 @@ class PredicateJoin : TestBase() { .plus(df1.toColoredHTML().wrap("df1")) .plus(df2.toColoredHTML().wrap("df2")) .plus( - df1.innerPredicateJoin(df2) { it["index"] == right["index"] && it["age"] == right["age"] } + df1.innerJoinWith(df2) { it["index"] == right["index"] && it["age"] == right["age"] } .toColoredHTML().wrap("result") ) .wrapRow() @@ -551,7 +552,7 @@ class PredicateJoin : TestBase() { fun compareLeft() { // SampleStart df1.leftJoin(df2, "index", "age") - df1.leftPredicateJoin(df2) { it["index"] == right["index"] && it["age"] == right["age"] } + df1.leftJoinWith(df2) { it["index"] == right["index"] && it["age"] == right["age"] } // SampleEnd PluginCallbackProxy.overrideHtmlOutput( @@ -571,7 +572,7 @@ class PredicateJoin : TestBase() { .plus(df1.toColoredHTML().wrap()) .plus(df2.toColoredHTML().wrap()) .plus( - df1.leftPredicateJoin(df2) { it["index"] == right["index"] && it["age"] == right["age"] } + df1.leftJoinWith(df2) { it["index"] == right["index"] && it["age"] == right["age"] } .toColoredHTML().wrap() ) .wrapRow() @@ -585,7 +586,7 @@ class PredicateJoin : TestBase() { fun compareRight() { // SampleStart df1.rightJoin(df2, "index", "age") - df1.rightPredicateJoin(df2) { it["index"] == right["index"] && it["age"] == right["age"] } + df1.rightJoinWith(df2) { it["index"] == right["index"] && it["age"] == right["age"] } // SampleEnd PluginCallbackProxy.overrideHtmlOutput( @@ -605,7 +606,7 @@ class PredicateJoin : TestBase() { .plus(df1.toColoredHTML().wrap()) .plus(df2.toColoredHTML().wrap()) .plus( - df1.rightPredicateJoin(df2) { it["index"] == right["index"] && it["age"] == right["age"] } + df1.rightJoinWith(df2) { it["index"] == right["index"] && it["age"] == right["age"] } .toColoredHTML().wrap() ) .wrapRow() diff --git a/core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/testSets/person/PredicateJoinTests.kt b/core/generated-sources/src/test/kotlin/org/jetbrains/kotlinx/dataframe/testSets/person/JoinWithTests.kt similarity index 61% rename from core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/testSets/person/PredicateJoinTests.kt rename to core/generated-sources/src/test/kotlin/org/jetbrains/kotlinx/dataframe/testSets/person/JoinWithTests.kt index 5c4d809710..39a5e9886c 100644 --- a/core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/testSets/person/PredicateJoinTests.kt +++ b/core/generated-sources/src/test/kotlin/org/jetbrains/kotlinx/dataframe/testSets/person/JoinWithTests.kt @@ -10,24 +10,24 @@ import org.jetbrains.kotlinx.dataframe.api.count import org.jetbrains.kotlinx.dataframe.api.dataFrameOf import org.jetbrains.kotlinx.dataframe.api.distinct import org.jetbrains.kotlinx.dataframe.api.excludeJoin -import org.jetbrains.kotlinx.dataframe.api.excludePredicateJoin +import org.jetbrains.kotlinx.dataframe.api.excludeJoinWith import org.jetbrains.kotlinx.dataframe.api.filter -import org.jetbrains.kotlinx.dataframe.api.filterPredicateJoin -import org.jetbrains.kotlinx.dataframe.api.fullPredicateJoin -import org.jetbrains.kotlinx.dataframe.api.innerPredicateJoin -import org.jetbrains.kotlinx.dataframe.api.leftPredicateJoin -import org.jetbrains.kotlinx.dataframe.api.predicateJoin +import org.jetbrains.kotlinx.dataframe.api.filterJoinWith +import org.jetbrains.kotlinx.dataframe.api.fullJoinWith +import org.jetbrains.kotlinx.dataframe.api.innerJoinWith +import org.jetbrains.kotlinx.dataframe.api.joinWith +import org.jetbrains.kotlinx.dataframe.api.leftJoinWith import org.jetbrains.kotlinx.dataframe.api.print import org.jetbrains.kotlinx.dataframe.api.remove -import org.jetbrains.kotlinx.dataframe.api.rightPredicateJoin +import org.jetbrains.kotlinx.dataframe.api.rightJoinWith import org.jetbrains.kotlinx.dataframe.api.select import org.junit.Test -class PredicateJoinTests : BaseJoinTest() { +class JoinWithTests : BaseJoinTest() { @Test fun `inner join`() { - val res = typed.predicateJoin(typed2) { + val res = typed.joinWith(typed2) { name == right.name && city == right.origin } res.columnsCount() shouldBe 8 @@ -40,7 +40,7 @@ class PredicateJoinTests : BaseJoinTest() { @Test fun `left join`() { - val res = typed.leftPredicateJoin(typed2) { name == right.name && city == right.origin } + val res = typed.leftJoinWith(typed2) { name == right.name && city == right.origin } res.columnsCount() shouldBe 8 res.rowsCount() shouldBe 10 @@ -52,7 +52,7 @@ class PredicateJoinTests : BaseJoinTest() { @Test fun `right join`() { - val res = typed.rightPredicateJoin(typed2) { + val res = typed.rightJoinWith(typed2) { name == right.name && city == right.origin } res.columnsCount() shouldBe 8 @@ -68,7 +68,7 @@ class PredicateJoinTests : BaseJoinTest() { @Test fun `outer join`() { - val res = typed.fullPredicateJoin(typed2) { name == right.name && city == right.origin } + val res = typed.fullJoinWith(typed2) { name == right.name && city == right.origin } println(res) res.columnsCount() shouldBe 8 res.rowsCount() shouldBe 12 @@ -81,20 +81,20 @@ class PredicateJoinTests : BaseJoinTest() { @Test fun `filter join`() { - val res = typed.filterPredicateJoin(typed2) { city == right.origin } - val expected = typed.innerPredicateJoin(typed2.select { origin }) { city == right.origin }.remove("origin") + val res = typed.filterJoinWith(typed2) { city == right.origin } + val expected = typed.innerJoinWith(typed2.select { origin }) { city == right.origin }.remove("origin") res shouldBe expected } @Test fun `filter not join`() { - val res = typed.excludePredicateJoin(typed2) { city == right.origin } + val res = typed.excludeJoinWith(typed2) { city == right.origin } res.rowsCount() shouldBe 3 res.city.toSet() shouldBe typed.city.toSet() - typed2.origin.toSet() val indexColumn = column("__index__") val withIndex = typed.addId(indexColumn) - val joined = withIndex.filterPredicateJoin(typed2) { city == right.origin } + val joined = withIndex.filterJoinWith(typed2) { city == right.origin } val joinedIndices = joined[indexColumn].toSet() val expected = withIndex.filter { !joinedIndices.contains(it[indexColumn]) }.remove(indexColumn) @@ -120,11 +120,11 @@ class PredicateJoinTests : BaseJoinTest() { @Test fun `test overloads contract`() { - typed.innerPredicateJoin(typed2) { name == right.name && city == right.origin } shouldBe typed.predicateJoin(typed2, JoinType.Inner) { name == right.name && city == right.origin } - typed.leftPredicateJoin(typed2) { name == right.name && city == right.origin } shouldBe typed.predicateJoin(typed2, JoinType.Left) { name == right.name && city == right.origin } - typed.rightPredicateJoin(typed2) { name == right.name && city == right.origin } shouldBe typed.predicateJoin(typed2, JoinType.Right) { name == right.name && city == right.origin } - typed.fullPredicateJoin(typed2) { name == right.name && city == right.origin } shouldBe typed.predicateJoin(typed2, JoinType.Full) { name == right.name && city == right.origin } - typed.excludePredicateJoin(typed2) { city == right.origin } shouldBe typed.predicateJoin(typed2, JoinType.Exclude) { city == right.origin } - typed.filterPredicateJoin(typed2) { city == right.origin } shouldBe typed.predicateJoin(typed2, JoinType.Filter) { city == right.origin } + typed.innerJoinWith(typed2) { name == right.name && city == right.origin } shouldBe typed.joinWith(typed2, JoinType.Inner) { name == right.name && city == right.origin } + typed.leftJoinWith(typed2) { name == right.name && city == right.origin } shouldBe typed.joinWith(typed2, JoinType.Left) { name == right.name && city == right.origin } + typed.rightJoinWith(typed2) { name == right.name && city == right.origin } shouldBe typed.joinWith(typed2, JoinType.Right) { name == right.name && city == right.origin } + typed.fullJoinWith(typed2) { name == right.name && city == right.origin } shouldBe typed.joinWith(typed2, JoinType.Full) { name == right.name && city == right.origin } + typed.excludeJoinWith(typed2) { city == right.origin } shouldBe typed.joinWith(typed2, JoinType.Exclude) { city == right.origin } + typed.filterJoinWith(typed2) { city == right.origin } shouldBe typed.joinWith(typed2, JoinType.Filter) { city == right.origin } } } diff --git a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/joinWith.kt b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/joinWith.kt new file mode 100644 index 0000000000..b5d4ef8f4c --- /dev/null +++ b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/joinWith.kt @@ -0,0 +1,50 @@ +package org.jetbrains.kotlinx.dataframe.api + +import org.jetbrains.kotlinx.dataframe.DataFrame +import org.jetbrains.kotlinx.dataframe.DataRow +import org.jetbrains.kotlinx.dataframe.Selector +import org.jetbrains.kotlinx.dataframe.impl.api.joinWithImpl + +public interface JoinedDataRow : DataRow { + public val right: DataRow +} + +public typealias JoinExpression = Selector, Boolean> + +public fun DataFrame.joinWith( + right: DataFrame, + type: JoinType = JoinType.Inner, + joinExpression: JoinExpression +): DataFrame { + return joinWithImpl(right, type, addNewColumns = type.addNewColumns, joinExpression) +} + +public fun DataFrame.innerJoinWith( + right: DataFrame, + joinExpression: JoinExpression +): DataFrame = joinWith(right, JoinType.Inner, joinExpression) + +public fun DataFrame.leftJoinWith( + right: DataFrame, + joinExpression: JoinExpression +): DataFrame = joinWith(right, JoinType.Left, joinExpression) + +public fun DataFrame.rightJoinWith( + right: DataFrame, + joinExpression: JoinExpression +): DataFrame = joinWith(right, JoinType.Right, joinExpression) + +public fun DataFrame.fullJoinWith( + right: DataFrame, + joinExpression: JoinExpression +): DataFrame = joinWith(right, JoinType.Full, joinExpression) + +public fun DataFrame.filterJoinWith( + right: DataFrame, + joinExpression: JoinExpression +): DataFrame = joinWithImpl(right, JoinType.Inner, addNewColumns = false, joinExpression) + +public fun DataFrame.excludeJoinWith( + right: DataFrame, + joinExpression: JoinExpression +): DataFrame = joinWithImpl(right, JoinType.Exclude, addNewColumns = false, joinExpression) diff --git a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/predicateJoin.kt b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/predicateJoin.kt deleted file mode 100644 index 1ccd42a52f..0000000000 --- a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/predicateJoin.kt +++ /dev/null @@ -1,50 +0,0 @@ -package org.jetbrains.kotlinx.dataframe.api - -import org.jetbrains.kotlinx.dataframe.DataFrame -import org.jetbrains.kotlinx.dataframe.DataRow -import org.jetbrains.kotlinx.dataframe.Selector -import org.jetbrains.kotlinx.dataframe.impl.api.predicateJoinImpl - -public interface JoinedDataRow : DataRow { - public val right: DataRow -} - -public typealias JoinExpression = Selector, Boolean> - -public fun DataFrame.predicateJoin( - right: DataFrame, - type: JoinType = JoinType.Inner, - joinExpression: JoinExpression -): DataFrame { - return predicateJoinImpl(right, type, addNewColumns = type.addNewColumns, joinExpression) -} - -public fun DataFrame.innerPredicateJoin( - right: DataFrame, - joinExpression: JoinExpression -): DataFrame = predicateJoin(right, JoinType.Inner, joinExpression) - -public fun DataFrame.leftPredicateJoin( - right: DataFrame, - joinExpression: JoinExpression -): DataFrame = predicateJoin(right, JoinType.Left, joinExpression) - -public fun DataFrame.rightPredicateJoin( - right: DataFrame, - joinExpression: JoinExpression -): DataFrame = predicateJoin(right, JoinType.Right, joinExpression) - -public fun DataFrame.fullPredicateJoin( - right: DataFrame, - joinExpression: JoinExpression -): DataFrame = predicateJoin(right, JoinType.Full, joinExpression) - -public fun DataFrame.filterPredicateJoin( - right: DataFrame, - joinExpression: JoinExpression -): DataFrame = predicateJoinImpl(right, JoinType.Inner, addNewColumns = false, joinExpression) - -public fun DataFrame.excludePredicateJoin( - right: DataFrame, - joinExpression: JoinExpression -): DataFrame = predicateJoinImpl(right, JoinType.Exclude, addNewColumns = false, joinExpression) diff --git a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/api/predicateJoin.kt b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/api/joinWith.kt similarity index 98% rename from core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/api/predicateJoin.kt rename to core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/api/joinWith.kt index 701a6875ea..306e4678bb 100644 --- a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/api/predicateJoin.kt +++ b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/api/joinWith.kt @@ -24,7 +24,7 @@ internal class JoinedDataRowImpl( override val right: DataRow = DataRowImpl(index1, rightOwner) } -internal fun DataFrame.predicateJoinImpl( +internal fun DataFrame.joinWithImpl( right: DataFrame, type: JoinType = JoinType.Inner, addNewColumns: Boolean, diff --git a/core/generated-sources/src/test/kotlin/org/jetbrains/kotlinx/dataframe/samples/api/PredicateJoin.kt b/core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/samples/api/JoinWith.kt similarity index 77% rename from core/generated-sources/src/test/kotlin/org/jetbrains/kotlinx/dataframe/samples/api/PredicateJoin.kt rename to core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/samples/api/JoinWith.kt index a28330e546..b9636e97b0 100644 --- a/core/generated-sources/src/test/kotlin/org/jetbrains/kotlinx/dataframe/samples/api/PredicateJoin.kt +++ b/core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/samples/api/JoinWith.kt @@ -16,16 +16,17 @@ import org.jetbrains.kotlinx.dataframe.api.colsOf import org.jetbrains.kotlinx.dataframe.api.column import org.jetbrains.kotlinx.dataframe.api.convert import org.jetbrains.kotlinx.dataframe.api.dataFrameOf -import org.jetbrains.kotlinx.dataframe.api.excludePredicateJoin -import org.jetbrains.kotlinx.dataframe.api.filterPredicateJoin -import org.jetbrains.kotlinx.dataframe.api.fullPredicateJoin +import org.jetbrains.kotlinx.dataframe.api.excludeJoinWith +import org.jetbrains.kotlinx.dataframe.api.filterJoinWith +import org.jetbrains.kotlinx.dataframe.api.fullJoinWith +import org.jetbrains.kotlinx.dataframe.api.getValue import org.jetbrains.kotlinx.dataframe.api.innerJoin -import org.jetbrains.kotlinx.dataframe.api.innerPredicateJoin +import org.jetbrains.kotlinx.dataframe.api.innerJoinWith +import org.jetbrains.kotlinx.dataframe.api.joinWith import org.jetbrains.kotlinx.dataframe.api.leftJoin -import org.jetbrains.kotlinx.dataframe.api.leftPredicateJoin -import org.jetbrains.kotlinx.dataframe.api.predicateJoin +import org.jetbrains.kotlinx.dataframe.api.leftJoinWith import org.jetbrains.kotlinx.dataframe.api.rightJoin -import org.jetbrains.kotlinx.dataframe.api.rightPredicateJoin +import org.jetbrains.kotlinx.dataframe.api.rightJoinWith import org.jetbrains.kotlinx.dataframe.api.with import org.jetbrains.kotlinx.dataframe.explainer.PluginCallbackProxy import org.jetbrains.kotlinx.dataframe.explainer.TransformDataFrameExpressions @@ -39,7 +40,7 @@ import org.jetbrains.kotlinx.dataframe.jupyter.RenderedContent import org.junit.Test import java.time.format.DateTimeFormatter -class PredicateJoin : TestBase() { +class JoinWith : TestBase() { @DataSchema interface Campaigns { @@ -218,265 +219,265 @@ class PredicateJoin : TestBase() { @TransformDataFrameExpressions @Test - fun predicateJoin_accessors() { + fun joinWith_accessors() { val result = run { // SampleStart val date by column() val startDate by column() val endDate by column() - campaigns.innerPredicateJoin(visits) { + campaigns.innerJoinWith(visits) { right[date] in startDate()..endDate() } // SampleEnd } - val coloredResult = coloredCampaigns.innerPredicateJoin(coloredVisits, joinExpression = joinExpression) + val coloredResult = coloredCampaigns.innerJoinWith(coloredVisits, joinExpression = joinExpression) snippetOutput(coloredResult, result) } @TransformDataFrameExpressions @Test - fun filterPredicateJoin_accessors() { + fun filterJoinWith_accessors() { val result = run { // SampleStart val date by column() val startDate by column() val endDate by column() - campaigns.filterPredicateJoin(visits) { + campaigns.filterJoinWith(visits) { right[date] in startDate()..endDate() } // SampleEnd } - val coloredResult = coloredCampaigns.filterPredicateJoin(coloredVisits, joinExpression = joinExpression) + val coloredResult = coloredCampaigns.filterJoinWith(coloredVisits, joinExpression = joinExpression) snippetOutput(coloredResult, result) } @TransformDataFrameExpressions @Test - fun leftPredicateJoin_accessors() { + fun leftJoinWith_accessors() { val result = run { // SampleStart val date by column() val startDate by column() val endDate by column() - campaigns.leftPredicateJoin(visits) { + campaigns.leftJoinWith(visits) { right[date] in startDate()..endDate() } // SampleEnd } - val coloredResult = coloredCampaigns.leftPredicateJoin(coloredVisits, joinExpression = joinExpression) + val coloredResult = coloredCampaigns.leftJoinWith(coloredVisits, joinExpression = joinExpression) snippetOutput(coloredResult, result) } @TransformDataFrameExpressions @Test - fun rightPredicateJoin_accessors() { + fun rightJoinWith_accessors() { val result = run { // SampleStart val date by column() val startDate by column() val endDate by column() - campaigns.rightPredicateJoin(visits) { + campaigns.rightJoinWith(visits) { right[date] in startDate()..endDate() } // SampleEnd } - val coloredResult = coloredCampaigns.rightPredicateJoin(coloredVisits, joinExpression = joinExpression) + val coloredResult = coloredCampaigns.rightJoinWith(coloredVisits, joinExpression = joinExpression) snippetOutput(coloredResult, result) } @TransformDataFrameExpressions @Test - fun fullPredicateJoin_accessors() { + fun fullJoinWith_accessors() { val result = run { // SampleStart val date by column() val startDate by column() val endDate by column() - campaigns.fullPredicateJoin(visits) { + campaigns.fullJoinWith(visits) { right[date] in startDate()..endDate() } // SampleEnd } - val coloredResult = coloredCampaigns.fullPredicateJoin(coloredVisits, joinExpression = joinExpression) + val coloredResult = coloredCampaigns.fullJoinWith(coloredVisits, joinExpression = joinExpression) snippetOutput(coloredResult, result) } @TransformDataFrameExpressions @Test - fun excludePredicateJoin_accessors() { + fun excludeJoinWith_accessors() { val result = run { // SampleStart val date by column() val startDate by column() val endDate by column() - campaigns.excludePredicateJoin(visits) { + campaigns.excludeJoinWith(visits) { right[date] in startDate()..endDate() } // SampleEnd } - val coloredResult = coloredCampaigns.excludePredicateJoin(coloredVisits, joinExpression = joinExpression) + val coloredResult = coloredCampaigns.excludeJoinWith(coloredVisits, joinExpression = joinExpression) snippetOutput(coloredResult, result) } @TransformDataFrameExpressions @Test - fun predicateJoin_strings() { + fun joinWith_strings() { val result = // SampleStart - campaigns.innerPredicateJoin(visits) { - right[{ "date"() }] in "startDate"().."endDate"() + campaigns.innerJoinWith(visits) { + right.getValue("date") in "startDate"().."endDate"() } // SampleEnd - val coloredResult = coloredCampaigns.innerPredicateJoin(coloredVisits, joinExpression = joinExpression) + val coloredResult = coloredCampaigns.innerJoinWith(coloredVisits, joinExpression = joinExpression) snippetOutput(coloredResult, result) } @TransformDataFrameExpressions @Test - fun filterPredicateJoin_strings() { + fun filterJoinWith_strings() { val result = // SampleStart - campaigns.filterPredicateJoin(visits) { - right[{ "date"() }] in "startDate"().."endDate"() + campaigns.filterJoinWith(visits) { + right.getValue("date") in "startDate"().."endDate"() } // SampleEnd - val coloredResult = coloredCampaigns.filterPredicateJoin(coloredVisits, joinExpression = joinExpression) + val coloredResult = coloredCampaigns.filterJoinWith(coloredVisits, joinExpression = joinExpression) snippetOutput(coloredResult, result) } @TransformDataFrameExpressions @Test - fun leftPredicateJoin_strings() { + fun leftJoinWith_strings() { val result = // SampleStart - campaigns.leftPredicateJoin(visits) { - right[{ "date"() }] in "startDate"().."endDate"() + campaigns.leftJoinWith(visits) { + right.getValue("date") in "startDate"().."endDate"() } // SampleEnd - val coloredResult = coloredCampaigns.leftPredicateJoin(coloredVisits, joinExpression = joinExpression) + val coloredResult = coloredCampaigns.leftJoinWith(coloredVisits, joinExpression = joinExpression) snippetOutput(coloredResult, result) } @TransformDataFrameExpressions @Test - fun rightPredicateJoin_strings() { + fun rightJoinWith_strings() { val result = // SampleStart - campaigns.rightPredicateJoin(visits) { - right[{ "date"() }] in "startDate"().."endDate"() + campaigns.rightJoinWith(visits) { + right.getValue("date") in "startDate"().."endDate"() } // SampleEnd - val coloredResult = coloredCampaigns.rightPredicateJoin(coloredVisits, joinExpression = joinExpression) + val coloredResult = coloredCampaigns.rightJoinWith(coloredVisits, joinExpression = joinExpression) snippetOutput(coloredResult, result) } @TransformDataFrameExpressions @Test - fun fullPredicateJoin_strings() { + fun fullJoinWith_strings() { val result = // SampleStart - campaigns.fullPredicateJoin(visits) { - right[{ "date"() }] in "startDate"().."endDate"() + campaigns.fullJoinWith(visits) { + right.getValue("date") in "startDate"().."endDate"() } // SampleEnd - val coloredResult = coloredCampaigns.fullPredicateJoin(coloredVisits, joinExpression = joinExpression) + val coloredResult = coloredCampaigns.fullJoinWith(coloredVisits, joinExpression = joinExpression) snippetOutput(coloredResult, result) } @TransformDataFrameExpressions @Test - fun excludePredicateJoin_strings() { + fun excludeJoinWith_strings() { val result = // SampleStart - campaigns.excludePredicateJoin(visits) { - right[{ "date"() }] in "startDate"().."endDate"() + campaigns.excludeJoinWith(visits) { + right.getValue("date") in "startDate"().."endDate"() } // SampleEnd - val coloredResult = coloredCampaigns.excludePredicateJoin(coloredVisits, joinExpression = joinExpression) + val coloredResult = coloredCampaigns.excludeJoinWith(coloredVisits, joinExpression = joinExpression) snippetOutput(coloredResult, result) } @TransformDataFrameExpressions @Test - fun predicateJoin_properties() { + fun joinWith_properties() { val result = // SampleStart - campaigns.innerPredicateJoin(visits) { + campaigns.innerJoinWith(visits) { right.date in startDate..endDate } // SampleEnd - val coloredResult = coloredCampaigns.innerPredicateJoin(coloredVisits, joinExpression = joinExpression) + val coloredResult = coloredCampaigns.innerJoinWith(coloredVisits, joinExpression = joinExpression) snippetOutput(coloredResult, result) } @TransformDataFrameExpressions @Test - fun filterPredicateJoin_properties() { + fun filterJoinWith_properties() { val result = // SampleStart - campaigns.filterPredicateJoin(visits) { + campaigns.filterJoinWith(visits) { right.date in startDate..endDate } // SampleEnd - val coloredResult = coloredCampaigns.filterPredicateJoin(coloredVisits, joinExpression = joinExpression) + val coloredResult = coloredCampaigns.filterJoinWith(coloredVisits, joinExpression = joinExpression) snippetOutput(coloredResult, result) } @TransformDataFrameExpressions @Test - fun leftPredicateJoin_properties() { + fun leftJoinWith_properties() { val result = // SampleStart - campaigns.leftPredicateJoin(visits) { + campaigns.leftJoinWith(visits) { right.date in startDate..endDate } // SampleEnd - val coloredResult = coloredCampaigns.leftPredicateJoin(coloredVisits, joinExpression = joinExpression) + val coloredResult = coloredCampaigns.leftJoinWith(coloredVisits, joinExpression = joinExpression) snippetOutput(coloredResult, result) } @TransformDataFrameExpressions @Test - fun rightPredicateJoin_properties() { + fun rightJoinWith_properties() { val result = // SampleStart - campaigns.rightPredicateJoin(visits) { + campaigns.rightJoinWith(visits) { right.date in startDate..endDate } // SampleEnd - val coloredResult = coloredCampaigns.rightPredicateJoin(coloredVisits, joinExpression = joinExpression) + val coloredResult = coloredCampaigns.rightJoinWith(coloredVisits, joinExpression = joinExpression) snippetOutput(coloredResult, result) } @TransformDataFrameExpressions @Test - fun fullPredicateJoin_properties() { + fun fullJoinWith_properties() { val result = // SampleStart - campaigns.fullPredicateJoin(visits) { + campaigns.fullJoinWith(visits) { right.date in startDate..endDate } // SampleEnd - val coloredResult = coloredCampaigns.fullPredicateJoin(coloredVisits, joinExpression = joinExpression) + val coloredResult = coloredCampaigns.fullJoinWith(coloredVisits, joinExpression = joinExpression) snippetOutput(coloredResult, result) } @TransformDataFrameExpressions @Test - fun excludePredicateJoin_properties() { + fun excludeJoinWith_properties() { val result = // SampleStart - campaigns.excludePredicateJoin(visits) { + campaigns.excludeJoinWith(visits) { right.date in startDate..endDate } // SampleEnd - val coloredResult = coloredCampaigns.excludePredicateJoin(coloredVisits, joinExpression = joinExpression) + val coloredResult = coloredCampaigns.excludeJoinWith(coloredVisits, joinExpression = joinExpression) snippetOutput(coloredResult, result) } @@ -485,9 +486,9 @@ class PredicateJoin : TestBase() { fun crossProduct() { val result = // SampleStart - campaigns.predicateJoin(visits) { true } + campaigns.joinWith(visits) { true } // SampleEnd - val coloredResult = coloredCampaigns.predicateJoin(coloredVisits) { true } + val coloredResult = coloredCampaigns.joinWith(coloredVisits) { true } snippetOutput(coloredResult, result) } @@ -527,7 +528,7 @@ class PredicateJoin : TestBase() { @Test fun compareInnerValues() { // SampleStart - df1.innerPredicateJoin(df2) { it["index"] == right["index"] && it["age"] == right["age"] } + df1.innerJoinWith(df2) { it["index"] == right["index"] && it["age"] == right["age"] } // SampleEnd PluginCallbackProxy.overrideHtmlOutput( @@ -537,7 +538,7 @@ class PredicateJoin : TestBase() { .plus(df1.toColoredHTML().wrap("df1")) .plus(df2.toColoredHTML().wrap("df2")) .plus( - df1.innerPredicateJoin(df2) { it["index"] == right["index"] && it["age"] == right["age"] } + df1.innerJoinWith(df2) { it["index"] == right["index"] && it["age"] == right["age"] } .toColoredHTML().wrap("result") ) .wrapRow() @@ -551,7 +552,7 @@ class PredicateJoin : TestBase() { fun compareLeft() { // SampleStart df1.leftJoin(df2, "index", "age") - df1.leftPredicateJoin(df2) { it["index"] == right["index"] && it["age"] == right["age"] } + df1.leftJoinWith(df2) { it["index"] == right["index"] && it["age"] == right["age"] } // SampleEnd PluginCallbackProxy.overrideHtmlOutput( @@ -571,7 +572,7 @@ class PredicateJoin : TestBase() { .plus(df1.toColoredHTML().wrap()) .plus(df2.toColoredHTML().wrap()) .plus( - df1.leftPredicateJoin(df2) { it["index"] == right["index"] && it["age"] == right["age"] } + df1.leftJoinWith(df2) { it["index"] == right["index"] && it["age"] == right["age"] } .toColoredHTML().wrap() ) .wrapRow() @@ -585,7 +586,7 @@ class PredicateJoin : TestBase() { fun compareRight() { // SampleStart df1.rightJoin(df2, "index", "age") - df1.rightPredicateJoin(df2) { it["index"] == right["index"] && it["age"] == right["age"] } + df1.rightJoinWith(df2) { it["index"] == right["index"] && it["age"] == right["age"] } // SampleEnd PluginCallbackProxy.overrideHtmlOutput( @@ -605,7 +606,7 @@ class PredicateJoin : TestBase() { .plus(df1.toColoredHTML().wrap()) .plus(df2.toColoredHTML().wrap()) .plus( - df1.rightPredicateJoin(df2) { it["index"] == right["index"] && it["age"] == right["age"] } + df1.rightJoinWith(df2) { it["index"] == right["index"] && it["age"] == right["age"] } .toColoredHTML().wrap() ) .wrapRow() diff --git a/core/generated-sources/src/test/kotlin/org/jetbrains/kotlinx/dataframe/testSets/person/PredicateJoinTests.kt b/core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/testSets/person/JoinWithTests.kt similarity index 61% rename from core/generated-sources/src/test/kotlin/org/jetbrains/kotlinx/dataframe/testSets/person/PredicateJoinTests.kt rename to core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/testSets/person/JoinWithTests.kt index 5c4d809710..39a5e9886c 100644 --- a/core/generated-sources/src/test/kotlin/org/jetbrains/kotlinx/dataframe/testSets/person/PredicateJoinTests.kt +++ b/core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/testSets/person/JoinWithTests.kt @@ -10,24 +10,24 @@ import org.jetbrains.kotlinx.dataframe.api.count import org.jetbrains.kotlinx.dataframe.api.dataFrameOf import org.jetbrains.kotlinx.dataframe.api.distinct import org.jetbrains.kotlinx.dataframe.api.excludeJoin -import org.jetbrains.kotlinx.dataframe.api.excludePredicateJoin +import org.jetbrains.kotlinx.dataframe.api.excludeJoinWith import org.jetbrains.kotlinx.dataframe.api.filter -import org.jetbrains.kotlinx.dataframe.api.filterPredicateJoin -import org.jetbrains.kotlinx.dataframe.api.fullPredicateJoin -import org.jetbrains.kotlinx.dataframe.api.innerPredicateJoin -import org.jetbrains.kotlinx.dataframe.api.leftPredicateJoin -import org.jetbrains.kotlinx.dataframe.api.predicateJoin +import org.jetbrains.kotlinx.dataframe.api.filterJoinWith +import org.jetbrains.kotlinx.dataframe.api.fullJoinWith +import org.jetbrains.kotlinx.dataframe.api.innerJoinWith +import org.jetbrains.kotlinx.dataframe.api.joinWith +import org.jetbrains.kotlinx.dataframe.api.leftJoinWith import org.jetbrains.kotlinx.dataframe.api.print import org.jetbrains.kotlinx.dataframe.api.remove -import org.jetbrains.kotlinx.dataframe.api.rightPredicateJoin +import org.jetbrains.kotlinx.dataframe.api.rightJoinWith import org.jetbrains.kotlinx.dataframe.api.select import org.junit.Test -class PredicateJoinTests : BaseJoinTest() { +class JoinWithTests : BaseJoinTest() { @Test fun `inner join`() { - val res = typed.predicateJoin(typed2) { + val res = typed.joinWith(typed2) { name == right.name && city == right.origin } res.columnsCount() shouldBe 8 @@ -40,7 +40,7 @@ class PredicateJoinTests : BaseJoinTest() { @Test fun `left join`() { - val res = typed.leftPredicateJoin(typed2) { name == right.name && city == right.origin } + val res = typed.leftJoinWith(typed2) { name == right.name && city == right.origin } res.columnsCount() shouldBe 8 res.rowsCount() shouldBe 10 @@ -52,7 +52,7 @@ class PredicateJoinTests : BaseJoinTest() { @Test fun `right join`() { - val res = typed.rightPredicateJoin(typed2) { + val res = typed.rightJoinWith(typed2) { name == right.name && city == right.origin } res.columnsCount() shouldBe 8 @@ -68,7 +68,7 @@ class PredicateJoinTests : BaseJoinTest() { @Test fun `outer join`() { - val res = typed.fullPredicateJoin(typed2) { name == right.name && city == right.origin } + val res = typed.fullJoinWith(typed2) { name == right.name && city == right.origin } println(res) res.columnsCount() shouldBe 8 res.rowsCount() shouldBe 12 @@ -81,20 +81,20 @@ class PredicateJoinTests : BaseJoinTest() { @Test fun `filter join`() { - val res = typed.filterPredicateJoin(typed2) { city == right.origin } - val expected = typed.innerPredicateJoin(typed2.select { origin }) { city == right.origin }.remove("origin") + val res = typed.filterJoinWith(typed2) { city == right.origin } + val expected = typed.innerJoinWith(typed2.select { origin }) { city == right.origin }.remove("origin") res shouldBe expected } @Test fun `filter not join`() { - val res = typed.excludePredicateJoin(typed2) { city == right.origin } + val res = typed.excludeJoinWith(typed2) { city == right.origin } res.rowsCount() shouldBe 3 res.city.toSet() shouldBe typed.city.toSet() - typed2.origin.toSet() val indexColumn = column("__index__") val withIndex = typed.addId(indexColumn) - val joined = withIndex.filterPredicateJoin(typed2) { city == right.origin } + val joined = withIndex.filterJoinWith(typed2) { city == right.origin } val joinedIndices = joined[indexColumn].toSet() val expected = withIndex.filter { !joinedIndices.contains(it[indexColumn]) }.remove(indexColumn) @@ -120,11 +120,11 @@ class PredicateJoinTests : BaseJoinTest() { @Test fun `test overloads contract`() { - typed.innerPredicateJoin(typed2) { name == right.name && city == right.origin } shouldBe typed.predicateJoin(typed2, JoinType.Inner) { name == right.name && city == right.origin } - typed.leftPredicateJoin(typed2) { name == right.name && city == right.origin } shouldBe typed.predicateJoin(typed2, JoinType.Left) { name == right.name && city == right.origin } - typed.rightPredicateJoin(typed2) { name == right.name && city == right.origin } shouldBe typed.predicateJoin(typed2, JoinType.Right) { name == right.name && city == right.origin } - typed.fullPredicateJoin(typed2) { name == right.name && city == right.origin } shouldBe typed.predicateJoin(typed2, JoinType.Full) { name == right.name && city == right.origin } - typed.excludePredicateJoin(typed2) { city == right.origin } shouldBe typed.predicateJoin(typed2, JoinType.Exclude) { city == right.origin } - typed.filterPredicateJoin(typed2) { city == right.origin } shouldBe typed.predicateJoin(typed2, JoinType.Filter) { city == right.origin } + typed.innerJoinWith(typed2) { name == right.name && city == right.origin } shouldBe typed.joinWith(typed2, JoinType.Inner) { name == right.name && city == right.origin } + typed.leftJoinWith(typed2) { name == right.name && city == right.origin } shouldBe typed.joinWith(typed2, JoinType.Left) { name == right.name && city == right.origin } + typed.rightJoinWith(typed2) { name == right.name && city == right.origin } shouldBe typed.joinWith(typed2, JoinType.Right) { name == right.name && city == right.origin } + typed.fullJoinWith(typed2) { name == right.name && city == right.origin } shouldBe typed.joinWith(typed2, JoinType.Full) { name == right.name && city == right.origin } + typed.excludeJoinWith(typed2) { city == right.origin } shouldBe typed.joinWith(typed2, JoinType.Exclude) { city == right.origin } + typed.filterJoinWith(typed2) { city == right.origin } shouldBe typed.joinWith(typed2, JoinType.Filter) { city == right.origin } } } diff --git a/docs/StardustDocs/d.tree b/docs/StardustDocs/d.tree index 477809c2df..8272d4702b 100644 --- a/docs/StardustDocs/d.tree +++ b/docs/StardustDocs/d.tree @@ -166,7 +166,7 @@ - + diff --git a/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.PredicateJoin.compareInnerColumns.html b/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.JoinWith.compareInnerColumns.html similarity index 100% rename from docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.PredicateJoin.compareInnerColumns.html rename to docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.JoinWith.compareInnerColumns.html diff --git a/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.PredicateJoin.compareInnerValues.html b/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.JoinWith.compareInnerValues.html similarity index 100% rename from docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.PredicateJoin.compareInnerValues.html rename to docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.JoinWith.compareInnerValues.html diff --git a/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.PredicateJoin.compareLeft.html b/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.JoinWith.compareLeft.html similarity index 100% rename from docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.PredicateJoin.compareLeft.html rename to docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.JoinWith.compareLeft.html diff --git a/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.PredicateJoin.compareRight.html b/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.JoinWith.compareRight.html similarity index 100% rename from docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.PredicateJoin.compareRight.html rename to docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.JoinWith.compareRight.html diff --git a/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.PredicateJoin.crossProduct.html b/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.JoinWith.crossProduct.html similarity index 100% rename from docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.PredicateJoin.crossProduct.html rename to docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.JoinWith.crossProduct.html diff --git a/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.PredicateJoin.excludePredicateJoin.html b/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.JoinWith.excludeJoinWith.html similarity index 100% rename from docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.PredicateJoin.excludePredicateJoin.html rename to docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.JoinWith.excludeJoinWith.html diff --git a/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.PredicateJoin.filterPredicateJoin.html b/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.JoinWith.filterJoinWith.html similarity index 98% rename from docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.PredicateJoin.filterPredicateJoin.html rename to docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.JoinWith.filterJoinWith.html index 2b3a05da98..a5e2aea1f3 100644 --- a/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.PredicateJoin.filterPredicateJoin.html +++ b/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.JoinWith.filterJoinWith.html @@ -190,17 +190,17 @@
campaigns -
+
visits -
+
result -
+
@@ -484,27 +484,27 @@ call_DataFrame(function() { DataFrame.addTable({ cols: [{ name: "name", children: [], rightAlign: false, values: [{ style: "background-color:#b3cde0;color:#000033", value: "Winter Sale"},{ style: "background-color:#ccebc5;color:#003300", value: "Spring Sale"},{ style: "background-color:#b0e0e6;color:#191970", value: "Summer Sale"},{ style: "background-color:#dda0dd;color:#551a8b", value: "Autumn Sale"}] }, { name: "startDate", children: [], rightAlign: false, values: [{ style: "background-color:#b3cde0;color:#000033", value: "01 January 2023"},{ style: "background-color:#ccebc5;color:#003300", value: "01 April 2023"},{ style: "background-color:#b0e0e6;color:#191970", value: "01 July 2023"},{ style: "background-color:#dda0dd;color:#551a8b", value: "01 October 2023"}] }, { name: "endDate", children: [], rightAlign: false, values: [{ style: "background-color:#b3cde0;color:#000033", value: "31 January 2023"},{ style: "background-color:#ccebc5;color:#003300", value: "30 April 2023"},{ style: "background-color:#b0e0e6;color:#191970", value: "31 July 2023"},{ style: "background-color:#dda0dd;color:#551a8b", value: "31 October 2023"}] }, -], id: 0, rootId: 0, totalRows: 4 } ) }); +], id: 2, rootId: 2, totalRows: 4 } ) }); /*-->*/ -call_DataFrame(function() { DataFrame.renderTable(0) }); +call_DataFrame(function() { DataFrame.renderTable(2) }); /**/ -call_DataFrame(function() { DataFrame.renderTable(1) }); +call_DataFrame(function() { DataFrame.renderTable(3) }); /**/ -call_DataFrame(function() { DataFrame.renderTable(2) }); +call_DataFrame(function() { DataFrame.renderTable(4) }); diff --git a/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.PredicateJoin.fullPredicateJoin.html b/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.JoinWith.fullJoinWith.html similarity index 100% rename from docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.PredicateJoin.fullPredicateJoin.html rename to docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.JoinWith.fullJoinWith.html diff --git a/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.PredicateJoin.predicateJoin.html b/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.JoinWith.joinWith.html similarity index 100% rename from docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.PredicateJoin.predicateJoin.html rename to docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.JoinWith.joinWith.html diff --git a/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.PredicateJoin.leftPredicateJoin.html b/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.JoinWith.leftJoinWith.html similarity index 100% rename from docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.PredicateJoin.leftPredicateJoin.html rename to docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.JoinWith.leftJoinWith.html diff --git a/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.PredicateJoin.rightPredicateJoin.html b/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.JoinWith.rightJoinWith.html similarity index 100% rename from docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.PredicateJoin.rightPredicateJoin.html rename to docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.JoinWith.rightJoinWith.html diff --git a/docs/StardustDocs/topics/predicateJoin.md b/docs/StardustDocs/topics/joinWith.md similarity index 68% rename from docs/StardustDocs/topics/predicateJoin.md rename to docs/StardustDocs/topics/joinWith.md index 8a314f8813..628db0a7a5 100644 --- a/docs/StardustDocs/topics/predicateJoin.md +++ b/docs/StardustDocs/topics/joinWith.md @@ -1,11 +1,11 @@ -[//]: # (title: predicateJoin) +[//]: # (title: joinWith) - + Joins two [`DataFrames`](DataFrame.md) by a join expression. ```kotlin -predicateJoin(otherDf, type = JoinType.Inner) { joinExpression } +joinWith(otherDf, type = JoinType.Inner) { joinExpression } joinExpression: JoinedDataRow.(JoinedDataRow) -> Boolean @@ -40,12 +40,12 @@ For every join type there is a shortcut operation: #### Inner join - + ```kotlin -campaigns.innerPredicateJoin(visits) { +campaigns.innerJoinWith(visits) { right.date in startDate..endDate } ``` @@ -58,7 +58,7 @@ val date by column() val startDate by column() val endDate by column() -campaigns.innerPredicateJoin(visits) { +campaigns.innerJoinWith(visits) { right[date] in startDate()..endDate() } ``` @@ -67,25 +67,25 @@ campaigns.innerPredicateJoin(visits) { ```kotlin -campaigns.innerPredicateJoin(visits) { +campaigns.innerJoinWith(visits) { right[{ "date"() }] in "startDate"().."endDate"() } ``` - + #### Filter join Special case of inner join when you only need the data from the left table. - + ```kotlin -campaigns.filterPredicateJoin(visits) { +campaigns.filterJoinWith(visits) { right.date in startDate..endDate } ``` @@ -98,7 +98,7 @@ val date by column() val startDate by column() val endDate by column() -campaigns.filterPredicateJoin(visits) { +campaigns.filterJoinWith(visits) { right[date] in startDate()..endDate() } ``` @@ -107,23 +107,23 @@ campaigns.filterPredicateJoin(visits) { ```kotlin -campaigns.filterPredicateJoin(visits) { +campaigns.filterJoinWith(visits) { right[{ "date"() }] in "startDate"().."endDate"() } ``` - + #### Left join - + ```kotlin -campaigns.leftPredicateJoin(visits) { +campaigns.leftJoinWith(visits) { right.date in startDate..endDate } ``` @@ -136,7 +136,7 @@ val date by column() val startDate by column() val endDate by column() -campaigns.leftPredicateJoin(visits) { +campaigns.leftJoinWith(visits) { right[date] in startDate()..endDate() } ``` @@ -145,23 +145,23 @@ campaigns.leftPredicateJoin(visits) { ```kotlin -campaigns.leftPredicateJoin(visits) { +campaigns.leftJoinWith(visits) { right[{ "date"() }] in "startDate"().."endDate"() } ``` - + #### Right join - + ```kotlin -campaigns.rightPredicateJoin(visits) { +campaigns.rightJoinWith(visits) { right.date in startDate..endDate } ``` @@ -174,7 +174,7 @@ val date by column() val startDate by column() val endDate by column() -campaigns.rightPredicateJoin(visits) { +campaigns.rightJoinWith(visits) { right[date] in startDate()..endDate() } ``` @@ -183,23 +183,23 @@ campaigns.rightPredicateJoin(visits) { ```kotlin -campaigns.rightPredicateJoin(visits) { +campaigns.rightJoinWith(visits) { right[{ "date"() }] in "startDate"().."endDate"() } ``` - + #### Full join - + ```kotlin -campaigns.fullPredicateJoin(visits) { +campaigns.fullJoinWith(visits) { right.date in startDate..endDate } ``` @@ -212,7 +212,7 @@ val date by column() val startDate by column() val endDate by column() -campaigns.fullPredicateJoin(visits) { +campaigns.fullJoinWith(visits) { right[date] in startDate()..endDate() } ``` @@ -221,25 +221,25 @@ campaigns.fullPredicateJoin(visits) { ```kotlin -campaigns.fullPredicateJoin(visits) { +campaigns.fullJoinWith(visits) { right[{ "date"() }] in "startDate"().."endDate"() } ``` - + #### Exclude join Can be viewed as **filterJoin** with logically opposite predicate - + ```kotlin -campaigns.excludePredicateJoin(visits) { +campaigns.excludeJoinWith(visits) { right.date in startDate..endDate } ``` @@ -252,7 +252,7 @@ val date by column() val startDate by column() val endDate by column() -campaigns.excludePredicateJoin(visits) { +campaigns.excludeJoinWith(visits) { right[date] in startDate()..endDate() } ``` @@ -261,13 +261,13 @@ campaigns.excludePredicateJoin(visits) { ```kotlin -campaigns.excludePredicateJoin(visits) { +campaigns.excludeJoinWith(visits) { right[{ "date"() }] in "startDate"().."endDate"() } ``` - + #### Cross join @@ -277,10 +277,10 @@ Can also be called cross product of two dataframes ```kotlin -campaigns.predicateJoin(visits) { true } +campaigns.joinWith(visits) { true } ``` - + ### Difference from join @@ -293,41 +293,41 @@ campaigns.predicateJoin(visits) { true } df1.innerJoin(df2, "index", "age") ``` - + Columns that were used in the condition: `index`, `age` - are present only once. Numerical suffix is used to disambiguate columns that are not used in the condition. -Compare it to an equivalent predicate join: +Compare it to an equivalent `joinWith`: ```kotlin -df1.innerPredicateJoin(df2) { it["index"] == right["index"] && it["age"] == right["age"] } +df1.innerJoinWith(df2) { it["index"] == right["index"] && it["age"] == right["age"] } ``` - + -Here columns from both dataframes are presented as is. So [join](join.md) is better suited for `equals` relation, and predicateJoin is for everything else. +Here columns from both dataframes are presented as is. So [join](join.md) is better suited for `equals` relation, and joinWith is for everything else. Below are two more examples with join types that allow mismatches. Note the difference in `null` values ```kotlin df1.leftJoin(df2, "index", "age") -df1.leftPredicateJoin(df2) { it["index"] == right["index"] && it["age"] == right["age"] } +df1.leftJoinWith(df2) { it["index"] == right["index"] && it["age"] == right["age"] } ``` - + ```kotlin df1.rightJoin(df2, "index", "age") -df1.rightPredicateJoin(df2) { it["index"] == right["index"] && it["age"] == right["age"] } +df1.rightJoinWith(df2) { it["index"] == right["index"] && it["age"] == right["age"] } ``` - + diff --git a/docs/StardustDocs/topics/multipleDataFrames.md b/docs/StardustDocs/topics/multipleDataFrames.md index e9b63b40d5..5f8f2d5cb1 100644 --- a/docs/StardustDocs/topics/multipleDataFrames.md +++ b/docs/StardustDocs/topics/multipleDataFrames.md @@ -4,4 +4,4 @@ * [`add`](add.md) — union of columns from several [`DataFrames`](DataFrame.md) * [`concat`](concat.md) — union of rows from several [`DataFrames`](DataFrame.md) * [`join`](join.md) — sql-like join of two [`DataFrames`](DataFrame.md) by key columns -* [`predicateJoin`](predicateJoin.md) — join of two [`DataFrames`](DataFrame.md) by an expression that evaluates joined [DataRows](DataRow.md) to Boolean +* [`joinWith`](joinWith.md) — join of two [`DataFrames`](DataFrame.md) by an expression that evaluates joined [DataRows](DataRow.md) to Boolean diff --git a/docs/StardustDocs/topics/operations.md b/docs/StardustDocs/topics/operations.md index 327743dc55..dec13b4c77 100644 --- a/docs/StardustDocs/topics/operations.md +++ b/docs/StardustDocs/topics/operations.md @@ -78,7 +78,7 @@ Most multiplex operations end with `into` or `with` function. The following nami * [inferType](inferType.md) — infer column type from column values * [insert](insert.md) — insert column * [join](join.md) — join [`DataFrames`](DataFrame.md) by key columns - * [predicateJoin](predicateJoin.md) — join [`DataFrames`](DataFrame.md) by an expression that evaluates joined [DataRows](DataRow.md) to Boolean +* [joinWith](joinWith.md) — join [`DataFrames`](DataFrame.md) by an expression that evaluates joined [DataRows](DataRow.md) to Boolean * [last](last.md) / [lastOrNull](last.md#lastornull) — find last row by condition * [map](map.md) — map columns into new [`DataFrame`](DataFrame.md) or [`DataColumn`](DataColumn.md) * [max](minmax.md) / [maxBy](minmax.md) / [maxOf](minmax.md) / [maxFor](minmax.md) — max of values From 1e07548c34cb7250d39888459770bf9bf5440fa5 Mon Sep 17 00:00:00 2001 From: Jolan Rensen Date: Wed, 9 Aug 2023 11:27:08 +0200 Subject: [PATCH 31/45] typo fix --- .../kotlin/org/jetbrains/kotlinx/dataframe/api/convertTo.kt | 2 +- .../kotlin/org/jetbrains/kotlinx/dataframe/api/convertTo.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/convertTo.kt b/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/convertTo.kt index 99f64b4d75..cea811b37e 100644 --- a/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/convertTo.kt +++ b/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/convertTo.kt @@ -17,7 +17,7 @@ import kotlin.reflect.KType import kotlin.reflect.typeOf /** - * Specifies how to handle columns in original dataframe that were not mathced to any column in destination dataframe schema. + * Specifies how to handle columns in original dataframe that were not matched to any column in destination dataframe schema. */ public enum class ExcessiveColumns { /** diff --git a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/convertTo.kt b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/convertTo.kt index 99f64b4d75..cea811b37e 100644 --- a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/convertTo.kt +++ b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/convertTo.kt @@ -17,7 +17,7 @@ import kotlin.reflect.KType import kotlin.reflect.typeOf /** - * Specifies how to handle columns in original dataframe that were not mathced to any column in destination dataframe schema. + * Specifies how to handle columns in original dataframe that were not matched to any column in destination dataframe schema. */ public enum class ExcessiveColumns { /** From 19247414a6b0bcf97ada802683e2347ef391efb1 Mon Sep 17 00:00:00 2001 From: Jolan Rensen Date: Wed, 9 Aug 2023 11:55:54 +0200 Subject: [PATCH 32/45] installing pre-commit hook --- core/build.gradle.kts | 40 +++++++++++++++++++++++++++------------ gradle/scripts/pre-commit | 11 +++++++++++ 2 files changed, 39 insertions(+), 12 deletions(-) create mode 100644 gradle/scripts/pre-commit diff --git a/core/build.gradle.kts b/core/build.gradle.kts index c4aa9ee4b1..660061b98e 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -154,6 +154,20 @@ tasks.withType { dependsOn(copySamplesOutputs) } +// This task installs the pre-commit hook to the local machine the first time the project is built +// The pre-commit hook contains the command to run processKDocsMain before each commit +val installGitPreCommitHook by tasks.creating(Copy::class) { + from(File(rootProject.rootDir, "gradle/scripts/pre-commit")) + into(File(rootProject.rootDir, ".git/hooks")) + fileMode = 755 +} +tasks.named("assemble") { + dependsOn(installGitPreCommitHook) +} + +// region docPreprocessor + +// This task is used to add all generated sources (from processKDocsMain) to git val generatedSourcesFolderName = "generated-sources" val addGeneratedSourcesToGit by tasks.creating(GitTask::class) { directory.set(file(".")) @@ -162,8 +176,8 @@ val addGeneratedSourcesToGit by tasks.creating(GitTask::class) { } // Backup the kotlin source files location -val kotlinMainSources = kotlin.sourceSets.main.get().kotlin.sourceDirectories -val kotlinTestSources = kotlin.sourceSets.test.get().kotlin.sourceDirectories +val kotlinMainSources: FileCollection = kotlin.sourceSets.main.get().kotlin.sourceDirectories +val kotlinTestSources: FileCollection = kotlin.sourceSets.test.get().kotlin.sourceDirectories fun pathOf(vararg parts: String) = parts.joinToString(File.separator) @@ -227,6 +241,18 @@ tasks.withType { } } +// If we want to use Dokka, make sure to use the preprocessed sources +tasks.withType { + dependsOn(processKDocsMain) + dokkaSourceSets { + all { + sourceRoot(processKDocsMain.target.get()) + } + } +} + +// endregion + korro { docs = fileTree(rootProject.rootDir) { include("docs/StardustDocs/topics/*.md") @@ -373,13 +399,3 @@ dataframes { name = "org.jetbrains.kotlinx.dataframe.samples.api.Repository" } } - -// If we want to use Dokka, make sure to use the preprocessed sources -tasks.withType { - dependsOn(processKDocsMain) - dokkaSourceSets { - all { - sourceRoot(processKDocsMain.target.get()) - } - } -} diff --git a/gradle/scripts/pre-commit b/gradle/scripts/pre-commit new file mode 100644 index 0000000000..0ddcd19920 --- /dev/null +++ b/gradle/scripts/pre-commit @@ -0,0 +1,11 @@ +#!/bin/sh + +echo "*****Running Doc Preprocessor******" + +./gradlew processKDocsMain + +status=$? + +echo "*****Done running Doc Preprocessor******" + +exit $status From e04e7c53b4ef5117439735aebbcd997cd54b34fd Mon Sep 17 00:00:00 2001 From: Jolan Rensen Date: Wed, 9 Aug 2023 14:03:15 +0200 Subject: [PATCH 33/45] attempt to fix build on TC --- core/build.gradle.kts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/build.gradle.kts b/core/build.gradle.kts index 660061b98e..1481266c43 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -157,6 +157,8 @@ tasks.withType { // This task installs the pre-commit hook to the local machine the first time the project is built // The pre-commit hook contains the command to run processKDocsMain before each commit val installGitPreCommitHook by tasks.creating(Copy::class) { + doNotTrackState(/* reasonNotToTrackState = */ "Fails on TeamCity otherwise.") + from(File(rootProject.rootDir, "gradle/scripts/pre-commit")) into(File(rootProject.rootDir, ".git/hooks")) fileMode = 755 From 6816cba23bcd77e170fb08871b5192bc8c885b75 Mon Sep 17 00:00:00 2001 From: Nikita Klimenko Date: Wed, 9 Aug 2023 15:09:42 +0300 Subject: [PATCH 34/45] review fixes --- docs/StardustDocs/topics/joinWith.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/StardustDocs/topics/joinWith.md b/docs/StardustDocs/topics/joinWith.md index 628db0a7a5..1bacce60e6 100644 --- a/docs/StardustDocs/topics/joinWith.md +++ b/docs/StardustDocs/topics/joinWith.md @@ -16,9 +16,9 @@ interface JoinedDataRow: LeftDataRow { } ``` -This function is a [join](join.md) variant that lets you match data using any expression that returns Boolean, +This function is a [join](join.md) variant that lets you match data using any expression that returns a Boolean, which also gives opportunity to perform operations that require values from both matching rows. -Can be helpful if data you want to join wasn't designed relational and requires heuristics to tell if rows are matching, +Can be helpful if the data you want to join wasn't designed relational and requires heuristics to tell if rows are matching, or has relations other than `equals`. For example, you can match rows based on: From 644fc6617ce4179fd6b94b4ba05ed0c364325eb5 Mon Sep 17 00:00:00 2001 From: Nikita Klimenko Date: Mon, 8 May 2023 14:05:24 +0300 Subject: [PATCH 35/45] update split condition so resulting iterable has multiple elements --- .../kotlinx/dataframe/samples/api/Modify.kt | 49 +- ...nx.dataframe.samples.api.Modify.split.html | 152 +---- ...x.dataframe.samples.api.Modify.split1.html | 591 ++++++++++++++++++ ...taframe.samples.api.Modify.splitRegex.html | 96 +-- ...aframe.samples.api.Modify.splitRegex1.html | 545 ++++++++++++++++ docs/StardustDocs/topics/split.md | 54 +- 6 files changed, 1243 insertions(+), 244 deletions(-) create mode 100644 docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.Modify.split1.html create mode 100644 docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.Modify.splitRegex1.html diff --git a/core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/samples/api/Modify.kt b/core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/samples/api/Modify.kt index 1a8bf5c505..374491133b 100644 --- a/core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/samples/api/Modify.kt +++ b/core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/samples/api/Modify.kt @@ -496,9 +496,7 @@ class Modify : TestBase() { @TransformDataFrameExpressions fun split_properties() { // SampleStart - df.split { name }.by { it.values() }.into("nameParts") - - df.split { name.lastName }.by(" ").default("").inward { "word$it" } + df.split { name.lastName }.by { it.asIterable() }.into("char1", "char2") // SampleEnd } @@ -509,9 +507,7 @@ class Modify : TestBase() { val name by columnGroup() val lastName by name.column() - df.split { name }.by { it.values() }.into("nameParts") - - df.split { lastName }.by(" ").default("").inward { "word$it" } + df.split { lastName }.by { it.asIterable() }.into("char1", "char2") // SampleEnd } @@ -519,18 +515,53 @@ class Modify : TestBase() { @TransformDataFrameExpressions fun split_strings() { // SampleStart - df.split { name }.by { it.values() }.into("nameParts") + df.split { "name"["lastName"]() }.by { it.asIterable() }.into("char1", "char2") + // SampleEnd + } + + @Test + @TransformDataFrameExpressions + fun split1_properties() { + // SampleStart + df.split { name.lastName }.by { it.asIterable() }.default(' ').inward { "char$it" } + // SampleEnd + } + + @Test + @TransformDataFrameExpressions + fun split1_accessors() { + // SampleStart + val name by columnGroup() + val lastName by name.column() - df.split { "name"["lastName"] }.by(" ").default("").inward { "word$it" } + df.split { lastName }.by { it.asIterable() }.default(' ').inward { "char$it" } + // SampleEnd + } + + @Test + @TransformDataFrameExpressions + fun split1_strings() { + // SampleStart + df.split { "name"["lastName"]() }.by { it.asIterable() }.default(' ').inward { "char$it" } // SampleEnd } @Test @TransformDataFrameExpressions fun splitRegex() { + // SampleStart val merged = df.merge { name.lastName and name.firstName }.by { it[0] + " (" + it[1] + ")" }.into("name") - val name by column() + // SampleEnd + } + + private val merged = df.merge { name.lastName and name.firstName }.by { it[0] + " (" + it[1] + ")" }.into("name") + + @Test + @TransformDataFrameExpressions + fun splitRegex1() { // SampleStart + val name by column() + merged.split { name } .match("""(.*) \((.*)\)""") .inward("firstName", "lastName") diff --git a/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.Modify.split.html b/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.Modify.split.html index 0c7339963b..066ae32b3a 100644 --- a/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.Modify.split.html +++ b/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.Modify.split.html @@ -182,25 +182,12 @@ - - - - - - - - - - - -
- df.split { name }.by { it.values() }.into("nameParts") - +
Input DataFrame: rowsCount = 7, columnsCount = 5
@@ -217,51 +204,14 @@ Step 2: SplitWithTransform
-

-
-
- Output DataFrame: rowsCount = 7, columnsCount = 6 -
- -

-
-
-
-
- df.split { name.lastName }.by(" ").default("").inward { "word$it" } - -
- Input DataFrame: rowsCount = 7, columnsCount = 5 -
- -

-
-
- Step 1: Split -
- -

-
-
- Step 2: SplitWithTransform -
- -

-
-
- Step 3: SplitWithTransform -
-

Output DataFrame: rowsCount = 7, columnsCount = 5 -
+

-
-
\ No newline at end of file diff --git a/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.Modify.split1.html b/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.Modify.split1.html new file mode 100644 index 0000000000..169b6e326e --- /dev/null +++ b/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.Modify.split1.html @@ -0,0 +1,591 @@ + + + + + + + + +
+ Input DataFrame: rowsCount = 7, columnsCount = 5 +
+ +

+
+
+ Step 1: Split +
+ +

+
+
+ Step 2: SplitWithTransform +
+ +

+
+
+ Step 3: SplitWithTransform +
+ +

+
+
+ Output DataFrame: rowsCount = 7, columnsCount = 5 +
+ +

+
+ + + \ No newline at end of file diff --git a/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.Modify.splitRegex.html b/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.Modify.splitRegex.html index fd00a081be..13ce92efeb 100644 --- a/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.Modify.splitRegex.html +++ b/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.Modify.splitRegex.html @@ -182,23 +182,12 @@ - - - - - - - - - -
- df.merge { name.lastName and name.firstName }.by { it[0] + " (" + it[1] + ")" }.into("name") - +
Input DataFrame: rowsCount = 7, columnsCount = 5
@@ -223,37 +212,6 @@

-
-
-
- merged.split { name }.match("""(.*) \((.*)\)""").inward("firstName", "lastName") - -
- Input DataFrame: rowsCount = 7, columnsCount = 5 -
- -

-
-
- Step 1: Split -
- -

-
-
- Step 2: SplitWithTransform -
- -

-
-
- Output DataFrame: rowsCount = 7, columnsCount = 5 -
- -

-
-
-
\ No newline at end of file diff --git a/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.Modify.splitRegex1.html b/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.Modify.splitRegex1.html new file mode 100644 index 0000000000..9a7d16348d --- /dev/null +++ b/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.Modify.splitRegex1.html @@ -0,0 +1,545 @@ + + + + + + + + +
+ Input DataFrame: rowsCount = 7, columnsCount = 5 +
+ +

+
+
+ Step 1: Split +
+ +

+
+
+ Step 2: SplitWithTransform +
+ +

+
+
+ Output DataFrame: rowsCount = 7, columnsCount = 5 +
+ +

+
+ + + \ No newline at end of file diff --git a/docs/StardustDocs/topics/split.md b/docs/StardustDocs/topics/split.md index 08e2ec1b98..4a2542e141 100644 --- a/docs/StardustDocs/topics/split.md +++ b/docs/StardustDocs/topics/split.md @@ -72,9 +72,7 @@ Default `columnNamesGenerator` generates column names `split1`, `split2`... ```kotlin -df.split { name }.by { it.values() }.into("nameParts") - -df.split { name.lastName }.by(" ").default("").inward { "word$it" } +df.split { name.lastName }.by { it.asIterable() }.into("char1", "char2") ``` @@ -84,35 +82,71 @@ df.split { name.lastName }.by(" ").default("").inward { "word$it" } val name by columnGroup() val lastName by name.column() -df.split { name }.by { it.values() }.into("nameParts") - -df.split { lastName }.by(" ").default("").inward { "word$it" } +df.split { lastName }.by { it.asIterable() }.into("char1", "char2") ``` ```kotlin -df.split { name }.by { it.values() }.into("nameParts") - -df.split { "name"["lastName"] }.by(" ").default("").inward { "word$it" } +df.split { "name"["lastName"]() }.by { it.asIterable() }.into("char1", "char2") ``` + + + + +```kotlin +df.split { name.lastName }.by { it.asIterable() }.default(' ').inward { "char$it" } +``` + + + + +```kotlin +val name by columnGroup() +val lastName by name.column() + +df.split { lastName }.by { it.asIterable() }.default(' ').inward { "char$it" } +``` + + + + +```kotlin +df.split { "name"["lastName"]() }.by { it.asIterable() }.default(' ').inward { "char$it" } +``` + + + + + `String` columns can also be split into group matches of [`Regex`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.text/-regex/) pattern: ```kotlin +val merged = df.merge { name.lastName and name.firstName }.by { it[0] + " (" + it[1] + ")" }.into("name") +``` + + + + + + +```kotlin +val name by column() + merged.split { name } .match("""(.*) \((.*)\)""") .inward("firstName", "lastName") ``` - + [`FrameColumn`](DataColumn.md#framecolumn) can be split into columns: From 783e82dcdaa6b1e14e474eb659b2523877b31533 Mon Sep 17 00:00:00 2001 From: Nikita Klimenko Date: Wed, 17 May 2023 14:13:17 +0300 Subject: [PATCH 36/45] add builder for creating df from third party data --- .../kotlinx/dataframe/api/constructors.kt | 30 +++++++++++++++++++ .../kotlinx/dataframe/impl/DataFrameImpl.kt | 2 +- .../kotlinx/dataframe/api/constructors.kt | 16 ++++++++++ .../kotlinx/dataframe/api/constructors.kt | 30 +++++++++++++++++++ .../kotlinx/dataframe/impl/DataFrameImpl.kt | 2 +- .../kotlinx/dataframe/api/constructors.kt | 16 ++++++++++ 6 files changed, 94 insertions(+), 2 deletions(-) create mode 100644 core/generated-sources/src/test/kotlin/org/jetbrains/kotlinx/dataframe/api/constructors.kt create mode 100644 core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/api/constructors.kt diff --git a/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/constructors.kt b/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/constructors.kt index 10f1ebb536..7854580d33 100644 --- a/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/constructors.kt +++ b/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/constructors.kt @@ -15,6 +15,7 @@ import org.jetbrains.kotlinx.dataframe.columns.ColumnReference import org.jetbrains.kotlinx.dataframe.columns.FrameColumn import org.jetbrains.kotlinx.dataframe.exceptions.DuplicateColumnNamesException import org.jetbrains.kotlinx.dataframe.exceptions.UnequalColumnSizesException +import org.jetbrains.kotlinx.dataframe.impl.ColumnNameGenerator import org.jetbrains.kotlinx.dataframe.impl.DataFrameImpl import org.jetbrains.kotlinx.dataframe.impl.asList import org.jetbrains.kotlinx.dataframe.impl.columnName @@ -23,6 +24,7 @@ import org.jetbrains.kotlinx.dataframe.impl.columns.createColumn import org.jetbrains.kotlinx.dataframe.impl.columns.createComputedColumnReference import org.jetbrains.kotlinx.dataframe.impl.columns.forceResolve import org.jetbrains.kotlinx.dataframe.impl.columns.unbox +import org.jetbrains.kotlinx.dataframe.impl.unnamedColumnPrefix import org.jetbrains.kotlinx.dataframe.size import kotlin.random.Random import kotlin.random.nextInt @@ -348,6 +350,34 @@ public class DataFrameBuilder(private val header: List) { public fun randomBoolean(nrow: Int): AnyFrame = fillNotNull(nrow) { Random.nextBoolean() } } +/** + * Helper class for implementing operations when column names can be potentially duplicated. + * For example, operations involving multiple dataframes, computed columns or parsing some third-party data + */ +public class DynamicDataFrameBuilder { + private var cols: MutableList = mutableListOf() + private val generator = ColumnNameGenerator() + + public fun add(col: AnyCol): String { + val uniqueName = if (col.name().isEmpty()) { + generator.addUnique(unnamedColumnPrefix) + } else { + generator.addUnique(col.name()) + } + val renamed = if (uniqueName != col.name()) { + col.rename(uniqueName) + } else { + col + } + cols.add(renamed) + return uniqueName + } + + public fun toDataFrame(): AnyFrame { + return dataFrameOf(cols) + } +} + /** * Returns [DataFrame] with no rows and no columns. * diff --git a/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/DataFrameImpl.kt b/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/DataFrameImpl.kt index 1881b97314..93fe387f83 100644 --- a/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/DataFrameImpl.kt +++ b/core/generated-sources/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/DataFrameImpl.kt @@ -27,7 +27,7 @@ import org.jetbrains.kotlinx.dataframe.impl.columns.resolveSingle import org.jetbrains.kotlinx.dataframe.io.renderToString import kotlin.reflect.KProperty -private const val unnamedColumnPrefix = "untitled" +internal const val unnamedColumnPrefix = "untitled" internal open class DataFrameImpl(cols: List, val nrow: Int) : DataFrame, AggregatableInternal { diff --git a/core/generated-sources/src/test/kotlin/org/jetbrains/kotlinx/dataframe/api/constructors.kt b/core/generated-sources/src/test/kotlin/org/jetbrains/kotlinx/dataframe/api/constructors.kt new file mode 100644 index 0000000000..ceb14767e5 --- /dev/null +++ b/core/generated-sources/src/test/kotlin/org/jetbrains/kotlinx/dataframe/api/constructors.kt @@ -0,0 +1,16 @@ +package org.jetbrains.kotlinx.dataframe.api + +import io.kotest.matchers.shouldBe +import org.junit.Test + +class ConstructorsTests { + + @Test + fun `untitled column naming`() { + val builder = DynamicDataFrameBuilder() + repeat(5) { + builder.add(columnOf(1, 2, 3)) + } + builder.toDataFrame() shouldBe dataFrameOf(List(5) { columnOf(1, 2, 3) }) + } +} diff --git a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/constructors.kt b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/constructors.kt index 10f1ebb536..7854580d33 100644 --- a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/constructors.kt +++ b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/api/constructors.kt @@ -15,6 +15,7 @@ import org.jetbrains.kotlinx.dataframe.columns.ColumnReference import org.jetbrains.kotlinx.dataframe.columns.FrameColumn import org.jetbrains.kotlinx.dataframe.exceptions.DuplicateColumnNamesException import org.jetbrains.kotlinx.dataframe.exceptions.UnequalColumnSizesException +import org.jetbrains.kotlinx.dataframe.impl.ColumnNameGenerator import org.jetbrains.kotlinx.dataframe.impl.DataFrameImpl import org.jetbrains.kotlinx.dataframe.impl.asList import org.jetbrains.kotlinx.dataframe.impl.columnName @@ -23,6 +24,7 @@ import org.jetbrains.kotlinx.dataframe.impl.columns.createColumn import org.jetbrains.kotlinx.dataframe.impl.columns.createComputedColumnReference import org.jetbrains.kotlinx.dataframe.impl.columns.forceResolve import org.jetbrains.kotlinx.dataframe.impl.columns.unbox +import org.jetbrains.kotlinx.dataframe.impl.unnamedColumnPrefix import org.jetbrains.kotlinx.dataframe.size import kotlin.random.Random import kotlin.random.nextInt @@ -348,6 +350,34 @@ public class DataFrameBuilder(private val header: List) { public fun randomBoolean(nrow: Int): AnyFrame = fillNotNull(nrow) { Random.nextBoolean() } } +/** + * Helper class for implementing operations when column names can be potentially duplicated. + * For example, operations involving multiple dataframes, computed columns or parsing some third-party data + */ +public class DynamicDataFrameBuilder { + private var cols: MutableList = mutableListOf() + private val generator = ColumnNameGenerator() + + public fun add(col: AnyCol): String { + val uniqueName = if (col.name().isEmpty()) { + generator.addUnique(unnamedColumnPrefix) + } else { + generator.addUnique(col.name()) + } + val renamed = if (uniqueName != col.name()) { + col.rename(uniqueName) + } else { + col + } + cols.add(renamed) + return uniqueName + } + + public fun toDataFrame(): AnyFrame { + return dataFrameOf(cols) + } +} + /** * Returns [DataFrame] with no rows and no columns. * diff --git a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/DataFrameImpl.kt b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/DataFrameImpl.kt index 1881b97314..93fe387f83 100644 --- a/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/DataFrameImpl.kt +++ b/core/src/main/kotlin/org/jetbrains/kotlinx/dataframe/impl/DataFrameImpl.kt @@ -27,7 +27,7 @@ import org.jetbrains.kotlinx.dataframe.impl.columns.resolveSingle import org.jetbrains.kotlinx.dataframe.io.renderToString import kotlin.reflect.KProperty -private const val unnamedColumnPrefix = "untitled" +internal const val unnamedColumnPrefix = "untitled" internal open class DataFrameImpl(cols: List, val nrow: Int) : DataFrame, AggregatableInternal { diff --git a/core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/api/constructors.kt b/core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/api/constructors.kt new file mode 100644 index 0000000000..ceb14767e5 --- /dev/null +++ b/core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/api/constructors.kt @@ -0,0 +1,16 @@ +package org.jetbrains.kotlinx.dataframe.api + +import io.kotest.matchers.shouldBe +import org.junit.Test + +class ConstructorsTests { + + @Test + fun `untitled column naming`() { + val builder = DynamicDataFrameBuilder() + repeat(5) { + builder.add(columnOf(1, 2, 3)) + } + builder.toDataFrame() shouldBe dataFrameOf(List(5) { columnOf(1, 2, 3) }) + } +} From 19b8ee248c0878f5bd57a6ea4cf69642aea5229f Mon Sep 17 00:00:00 2001 From: Nikita Klimenko Date: Wed, 17 May 2023 14:28:21 +0300 Subject: [PATCH 37/45] documentation for DynamicDataFrameBuilder --- .../explainer/PluginCallbackProxy.kt | 69 ++- .../kotlinx/dataframe/samples/api/Create.kt | 19 + .../explainer/PluginCallbackProxy.kt | 69 ++- .../kotlinx/dataframe/samples/api/Create.kt | 19 + ...pi.Create.createDataFrameFromIterable.html | 476 ++++++++++++++++++ ...les.api.Create.createDataFrameFromMap.html | 476 ++++++++++++++++++ ....samples.api.Create.duplicatedColumns.html | 476 ++++++++++++++++++ docs/StardustDocs/topics/createDataFrame.md | 27 + 8 files changed, 1579 insertions(+), 52 deletions(-) create mode 100644 docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.Create.createDataFrameFromIterable.html create mode 100644 docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.Create.createDataFrameFromMap.html create mode 100644 docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.Create.duplicatedColumns.html diff --git a/core/generated-sources/src/test/kotlin/org/jetbrains/kotlinx/dataframe/explainer/PluginCallbackProxy.kt b/core/generated-sources/src/test/kotlin/org/jetbrains/kotlinx/dataframe/explainer/PluginCallbackProxy.kt index c2223087ec..c3d34c30ed 100644 --- a/core/generated-sources/src/test/kotlin/org/jetbrains/kotlinx/dataframe/explainer/PluginCallbackProxy.kt +++ b/core/generated-sources/src/test/kotlin/org/jetbrains/kotlinx/dataframe/explainer/PluginCallbackProxy.kt @@ -155,50 +155,67 @@ object PluginCallbackProxy : PluginCallback { ) } + private fun List.joinToSource(): String = + joinToString(".") { it.source } + private fun statementOutput( expressions: List, ): DataFrameHtmlData { var data = DataFrameHtmlData() - if (expressions.size < 2) error("Sample without output or input (i.e. function returns some value)") - for ((i, expression) in expressions.withIndex()) { - when (i) { - 0 -> { - val table = convertToHTML(expression.df) - val description = table.copy( - body = """ + val allow = setOf( + "toDataFrame", "peek(dataFrameOf(col), dataFrameOf(col))" + ) + if (expressions.isEmpty()) { + error("No dataframe expressions in sample") + } + if (expressions.size == 1) { + if (allow.any { expressions[0].source.contains(it) }) { + val expression = expressions[0] + data += convertToHTML(expression.df) + } else { + error("${expressions.joinToSource()} Sample without output or input (i.e. function returns some value)") + } + } else { + for ((i, expression) in expressions.withIndex()) { + when (i) { + 0 -> { + val table = convertToHTML(expression.df) + val description = table.copy( + body = """
Input ${convertToDescription(expression.df)} ${table.body}
- """.trimIndent() - ) - data += description - } + """.trimIndent() + ) + data += description + } - expressions.lastIndex -> { - val table = convertToHTML(expression.df) - val description = table.copy( - body = """ + expressions.lastIndex -> { + val table = convertToHTML(expression.df) + val description = table.copy( + body = """
Output ${convertToDescription(expression.df)} ${table.body}
- """.trimIndent() - ) - data += description - } + """.trimIndent() + ) + data += description + } - else -> { - val table = convertToHTML(expression.df) - val description = table.copy( - body = """ + else -> { + val table = convertToHTML(expression.df) + val description = table.copy( + body = """
Step $i: ${convertToDescription(expression.df)} ${table.body}
- """.trimIndent() - ) - data += description + """.trimIndent() + ) + data += description + } } } } diff --git a/core/generated-sources/src/test/kotlin/org/jetbrains/kotlinx/dataframe/samples/api/Create.kt b/core/generated-sources/src/test/kotlin/org/jetbrains/kotlinx/dataframe/samples/api/Create.kt index 13a0943580..8584a85608 100644 --- a/core/generated-sources/src/test/kotlin/org/jetbrains/kotlinx/dataframe/samples/api/Create.kt +++ b/core/generated-sources/src/test/kotlin/org/jetbrains/kotlinx/dataframe/samples/api/Create.kt @@ -1,7 +1,9 @@ package org.jetbrains.kotlinx.dataframe.samples.api import io.kotest.matchers.shouldBe +import org.jetbrains.kotlinx.dataframe.AnyFrame import org.jetbrains.kotlinx.dataframe.DataFrame +import org.jetbrains.kotlinx.dataframe.api.DynamicDataFrameBuilder import org.jetbrains.kotlinx.dataframe.api.Infer import org.jetbrains.kotlinx.dataframe.api.ValueProperty import org.jetbrains.kotlinx.dataframe.api.add @@ -431,4 +433,21 @@ class Create : TestBase() { df["scores"].kind shouldBe ColumnKind.Frame df["summary"]["min score"].values() shouldBe listOf(3, 5) } + + @Test + @TransformDataFrameExpressions + fun duplicatedColumns() { + // SampleStart + fun peek(vararg dataframes: AnyFrame): AnyFrame { + val builder = DynamicDataFrameBuilder() + for (df in dataframes) { + df.columns().firstOrNull()?.let { builder.add(it) } + } + return builder.toDataFrame() + } + + val col by columnOf(1, 2, 3) + peek(dataFrameOf(col), dataFrameOf(col)) + // SampleEnd + } } diff --git a/core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/explainer/PluginCallbackProxy.kt b/core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/explainer/PluginCallbackProxy.kt index c2223087ec..c3d34c30ed 100644 --- a/core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/explainer/PluginCallbackProxy.kt +++ b/core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/explainer/PluginCallbackProxy.kt @@ -155,50 +155,67 @@ object PluginCallbackProxy : PluginCallback { ) } + private fun List.joinToSource(): String = + joinToString(".") { it.source } + private fun statementOutput( expressions: List, ): DataFrameHtmlData { var data = DataFrameHtmlData() - if (expressions.size < 2) error("Sample without output or input (i.e. function returns some value)") - for ((i, expression) in expressions.withIndex()) { - when (i) { - 0 -> { - val table = convertToHTML(expression.df) - val description = table.copy( - body = """ + val allow = setOf( + "toDataFrame", "peek(dataFrameOf(col), dataFrameOf(col))" + ) + if (expressions.isEmpty()) { + error("No dataframe expressions in sample") + } + if (expressions.size == 1) { + if (allow.any { expressions[0].source.contains(it) }) { + val expression = expressions[0] + data += convertToHTML(expression.df) + } else { + error("${expressions.joinToSource()} Sample without output or input (i.e. function returns some value)") + } + } else { + for ((i, expression) in expressions.withIndex()) { + when (i) { + 0 -> { + val table = convertToHTML(expression.df) + val description = table.copy( + body = """
Input ${convertToDescription(expression.df)} ${table.body}
- """.trimIndent() - ) - data += description - } + """.trimIndent() + ) + data += description + } - expressions.lastIndex -> { - val table = convertToHTML(expression.df) - val description = table.copy( - body = """ + expressions.lastIndex -> { + val table = convertToHTML(expression.df) + val description = table.copy( + body = """
Output ${convertToDescription(expression.df)} ${table.body}
- """.trimIndent() - ) - data += description - } + """.trimIndent() + ) + data += description + } - else -> { - val table = convertToHTML(expression.df) - val description = table.copy( - body = """ + else -> { + val table = convertToHTML(expression.df) + val description = table.copy( + body = """
Step $i: ${convertToDescription(expression.df)} ${table.body}
- """.trimIndent() - ) - data += description + """.trimIndent() + ) + data += description + } } } } diff --git a/core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/samples/api/Create.kt b/core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/samples/api/Create.kt index 13a0943580..8584a85608 100644 --- a/core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/samples/api/Create.kt +++ b/core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/samples/api/Create.kt @@ -1,7 +1,9 @@ package org.jetbrains.kotlinx.dataframe.samples.api import io.kotest.matchers.shouldBe +import org.jetbrains.kotlinx.dataframe.AnyFrame import org.jetbrains.kotlinx.dataframe.DataFrame +import org.jetbrains.kotlinx.dataframe.api.DynamicDataFrameBuilder import org.jetbrains.kotlinx.dataframe.api.Infer import org.jetbrains.kotlinx.dataframe.api.ValueProperty import org.jetbrains.kotlinx.dataframe.api.add @@ -431,4 +433,21 @@ class Create : TestBase() { df["scores"].kind shouldBe ColumnKind.Frame df["summary"]["min score"].values() shouldBe listOf(3, 5) } + + @Test + @TransformDataFrameExpressions + fun duplicatedColumns() { + // SampleStart + fun peek(vararg dataframes: AnyFrame): AnyFrame { + val builder = DynamicDataFrameBuilder() + for (df in dataframes) { + df.columns().firstOrNull()?.let { builder.add(it) } + } + return builder.toDataFrame() + } + + val col by columnOf(1, 2, 3) + peek(dataFrameOf(col), dataFrameOf(col)) + // SampleEnd + } } diff --git a/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.Create.createDataFrameFromIterable.html b/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.Create.createDataFrameFromIterable.html new file mode 100644 index 0000000000..f0f27e06d8 --- /dev/null +++ b/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.Create.createDataFrameFromIterable.html @@ -0,0 +1,476 @@ + + + + + + + + +
+ +

+ + + \ No newline at end of file diff --git a/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.Create.createDataFrameFromMap.html b/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.Create.createDataFrameFromMap.html new file mode 100644 index 0000000000..f0f27e06d8 --- /dev/null +++ b/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.Create.createDataFrameFromMap.html @@ -0,0 +1,476 @@ + + + + + + + + +
+ +

+ + + \ No newline at end of file diff --git a/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.Create.duplicatedColumns.html b/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.Create.duplicatedColumns.html new file mode 100644 index 0000000000..958449a85d --- /dev/null +++ b/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.Create.duplicatedColumns.html @@ -0,0 +1,476 @@ + + + + + + + + +
+ +

+ + + \ No newline at end of file diff --git a/docs/StardustDocs/topics/createDataFrame.md b/docs/StardustDocs/topics/createDataFrame.md index 369909be18..54bb266b92 100644 --- a/docs/StardustDocs/topics/createDataFrame.md +++ b/docs/StardustDocs/topics/createDataFrame.md @@ -119,6 +119,7 @@ val age by columnOf(15, 20, 22) listOf(name, age).toDataFrame() ``` + `DataFrame` from `Map>`: @@ -132,6 +133,7 @@ val map = mapOf("name" to listOf("Alice", "Bob", "Charlie"), "age" to listOf(15, map.toDataFrame() ``` + Creates a [`DataFrame`](DataFrame.md) from an [`Iterable`](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-iterable/) of [basic types](https://kotlinlang.org/docs/basic-types.html) (except arrays): @@ -213,3 +215,28 @@ val df = students.toDataFrame { ``` + +### DynamicDataFrameBuilder + +Previously mentioned dataframe constructors throw an exception when column names are duplicated. +When implementing a custom operation involving multiple dataframes, computed columns or parsing some third-party data, +it might be desirable to disambiguate column names instead of throwing an exception. + + + +```kotlin +fun peek(vararg dataframes: AnyFrame): AnyFrame { + val builder = DynamicDataFrameBuilder() + for (df in dataframes) { + df.columns().firstOrNull()?.let { builder.add(it) } + } + return builder.toDataFrame() +} + +val col by columnOf(1, 2, 3) +peek(dataFrameOf(col), dataFrameOf(col)) +``` + + + + From aaa585f56490e1cef5a1f150f710a3126293b787 Mon Sep 17 00:00:00 2001 From: Nikita Klimenko Date: Wed, 17 May 2023 15:30:31 +0300 Subject: [PATCH 38/45] update split docs --- .../kotlinx/dataframe/samples/api/Modify.kt | 28 ++++++++----- ...frame.samples.api.Modify.splitInplace.html | 20 +++++----- ...rame.samples.api.Modify.splitIntoRows.html | 40 +++++++++---------- docs/StardustDocs/topics/split.md | 28 ++++++++----- 4 files changed, 66 insertions(+), 50 deletions(-) diff --git a/core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/samples/api/Modify.kt b/core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/samples/api/Modify.kt index 374491133b..82d0a081b6 100644 --- a/core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/samples/api/Modify.kt +++ b/core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/samples/api/Modify.kt @@ -469,7 +469,7 @@ class Modify : TestBase() { @TransformDataFrameExpressions fun splitInplace_properties() { // SampleStart - df.split { name.firstName }.by { it.chars().toList() }.inplace() + df.split { name.firstName }.by { it.asIterable() }.inplace() // SampleEnd } @@ -480,7 +480,7 @@ class Modify : TestBase() { val name by columnGroup() val firstName by name.column() - df.split { firstName }.by { it.chars().toList() }.inplace() + df.split { firstName }.by { it.asIterable() }.inplace() // SampleEnd } @@ -488,7 +488,7 @@ class Modify : TestBase() { @TransformDataFrameExpressions fun splitInplace_strings() { // SampleStart - df.split { "name"["firstName"]() }.by { it.chars().toList() }.inplace() + df.split { "name"["firstName"]() }.by { it.asIterable() }.inplace() // SampleEnd } @@ -523,7 +523,9 @@ class Modify : TestBase() { @TransformDataFrameExpressions fun split1_properties() { // SampleStart - df.split { name.lastName }.by { it.asIterable() }.default(' ').inward { "char$it" } + df.split { name.lastName } + .by { it.asIterable() }.default(' ') + .inward { "char$it" } // SampleEnd } @@ -534,7 +536,9 @@ class Modify : TestBase() { val name by columnGroup() val lastName by name.column() - df.split { lastName }.by { it.asIterable() }.default(' ').inward { "char$it" } + df.split { lastName } + .by { it.asIterable() }.default(' ') + .inward { "char$it" } // SampleEnd } @@ -542,7 +546,9 @@ class Modify : TestBase() { @TransformDataFrameExpressions fun split1_strings() { // SampleStart - df.split { "name"["lastName"]() }.by { it.asIterable() }.default(' ').inward { "char$it" } + df.split { "name"["lastName"]() } + .by { it.asIterable() }.default(' ') + .inward { "char$it" } // SampleEnd } @@ -550,7 +556,9 @@ class Modify : TestBase() { @TransformDataFrameExpressions fun splitRegex() { // SampleStart - val merged = df.merge { name.lastName and name.firstName }.by { it[0] + " (" + it[1] + ")" }.into("name") + val merged = df.merge { name.lastName and name.firstName } + .by { it[0] + " (" + it[1] + ")" } + .into("name") // SampleEnd } @@ -593,7 +601,7 @@ class Modify : TestBase() { @TransformDataFrameExpressions fun splitIntoRows_properties() { // SampleStart - df.split { name.firstName }.by { it.chars().toList() }.intoRows() + df.split { name.firstName }.by { it.asIterable() }.intoRows() df.split { name }.by { it.values() }.intoRows() // SampleEnd @@ -606,7 +614,7 @@ class Modify : TestBase() { val name by columnGroup() val firstName by name.column() - df.split { firstName }.by { it.chars().toList() }.intoRows() + df.split { firstName }.by { it.asIterable() }.intoRows() df.split { name }.by { it.values() }.intoRows() // SampleEnd @@ -616,7 +624,7 @@ class Modify : TestBase() { @TransformDataFrameExpressions fun splitIntoRows_strings() { // SampleStart - df.split { "name"["firstName"]() }.by { it.chars().toList() }.intoRows() + df.split { "name"["firstName"]() }.by { it.asIterable() }.intoRows() df.split { colGroup("name") }.by { it.values() }.intoRows() // SampleEnd diff --git a/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.Modify.splitInplace.html b/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.Modify.splitInplace.html index cb30c9ae00..743a4e3323 100644 --- a/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.Modify.splitInplace.html +++ b/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.Modify.splitInplace.html @@ -519,15 +519,15 @@ /* ```kotlin -val merged = df.merge { name.lastName and name.firstName }.by { it[0] + " (" + it[1] + ")" }.into("name") +val merged = df.merge { name.lastName and name.firstName } + .by { it[0] + " (" + it[1] + ")" } + .into("name") ``` @@ -185,7 +193,7 @@ Use `.intoRows()` terminal operation in `split` configuration to spread split va ```kotlin -df.split { name.firstName }.by { it.chars().toList() }.intoRows() +df.split { name.firstName }.by { it.asIterable() }.intoRows() df.split { name }.by { it.values() }.intoRows() ``` @@ -197,7 +205,7 @@ df.split { name }.by { it.values() }.intoRows() val name by columnGroup() val firstName by name.column() -df.split { firstName }.by { it.chars().toList() }.intoRows() +df.split { firstName }.by { it.asIterable() }.intoRows() df.split { name }.by { it.values() }.intoRows() ``` @@ -206,7 +214,7 @@ df.split { name }.by { it.values() }.intoRows() ```kotlin -df.split { "name"["firstName"]() }.by { it.chars().toList() }.intoRows() +df.split { "name"["firstName"]() }.by { it.asIterable() }.intoRows() df.split { colGroup("name") }.by { it.values() }.intoRows() ``` From c0aedcd147f5b520e1a9199da774dad8ffec555e Mon Sep 17 00:00:00 2001 From: Nikita Klimenko Date: Fri, 19 May 2023 14:56:31 +0300 Subject: [PATCH 39/45] migrate xml schema location due to changes in Writerside --- docs/StardustDocs/c.list | 2 +- docs/StardustDocs/cfg/build-script.xml | 2 +- docs/StardustDocs/cfg/buildprofiles.xml | 2 +- docs/StardustDocs/d.tree | 2 +- docs/StardustDocs/project.ihp | 2 +- docs/StardustDocs/r.list | 2 +- docs/StardustDocs/redirection-rules.xml | 2 +- docs/StardustDocs/v.list | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/StardustDocs/c.list b/docs/StardustDocs/c.list index e97afd856f..8339a6eb7d 100644 --- a/docs/StardustDocs/c.list +++ b/docs/StardustDocs/c.list @@ -1,6 +1,6 @@ + SYSTEM "https://resources.jetbrains.com/writerside/1.0/categories.dtd"> diff --git a/docs/StardustDocs/cfg/build-script.xml b/docs/StardustDocs/cfg/build-script.xml index 0118bbec2c..10cda55263 100644 --- a/docs/StardustDocs/cfg/build-script.xml +++ b/docs/StardustDocs/cfg/build-script.xml @@ -1,5 +1,5 @@ + SYSTEM "https://resources.jetbrains.com/writerside/1.0/build-script.dtd"> diff --git a/docs/StardustDocs/cfg/buildprofiles.xml b/docs/StardustDocs/cfg/buildprofiles.xml index a0ccbf802f..41f924fb36 100644 --- a/docs/StardustDocs/cfg/buildprofiles.xml +++ b/docs/StardustDocs/cfg/buildprofiles.xml @@ -1,6 +1,6 @@ - https://kotlin.github.io/dataframe/ diff --git a/docs/StardustDocs/d.tree b/docs/StardustDocs/d.tree index 8272d4702b..b1d1c72798 100644 --- a/docs/StardustDocs/d.tree +++ b/docs/StardustDocs/d.tree @@ -1,6 +1,6 @@ + SYSTEM "https://resources.jetbrains.com/writerside/1.0/product-profile.dtd"> - + diff --git a/docs/StardustDocs/r.list b/docs/StardustDocs/r.list index fc3c4bf694..bf01304e53 100644 --- a/docs/StardustDocs/r.list +++ b/docs/StardustDocs/r.list @@ -1,5 +1,5 @@ - + diff --git a/docs/StardustDocs/redirection-rules.xml b/docs/StardustDocs/redirection-rules.xml index 3725ab4d21..654fc8703f 100644 --- a/docs/StardustDocs/redirection-rules.xml +++ b/docs/StardustDocs/redirection-rules.xml @@ -1,5 +1,5 @@ - + Created after removal of "About Dataframe" from Dataframe diff --git a/docs/StardustDocs/v.list b/docs/StardustDocs/v.list index 245c641eba..6c3cf8012f 100644 --- a/docs/StardustDocs/v.list +++ b/docs/StardustDocs/v.list @@ -1,5 +1,5 @@ - + From b4fc60eee58c3d9d0c69bc2deba1ca3004b87da2 Mon Sep 17 00:00:00 2001 From: Nikita Klimenko Date: Fri, 19 May 2023 14:58:32 +0300 Subject: [PATCH 40/45] add spaces in title to make them easier to read --- docs/StardustDocs/topics/addRemove.md | 2 +- docs/StardustDocs/topics/appendDuplicate.md | 2 +- docs/StardustDocs/topics/explodeImplode.md | 2 +- docs/StardustDocs/topics/groupByConcat.md | 2 +- docs/StardustDocs/topics/groupUngroupFlatten.md | 2 +- docs/StardustDocs/topics/insertReplace.md | 2 +- docs/StardustDocs/topics/moveRename.md | 2 +- docs/StardustDocs/topics/pivotGather.md | 2 +- docs/StardustDocs/topics/splitMerge.md | 2 +- docs/StardustDocs/topics/updateConvert.md | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/StardustDocs/topics/addRemove.md b/docs/StardustDocs/topics/addRemove.md index e6d4bb1b32..5b4e21ff87 100644 --- a/docs/StardustDocs/topics/addRemove.md +++ b/docs/StardustDocs/topics/addRemove.md @@ -1,4 +1,4 @@ -[//]: # (title: Add/map/remove columns) +[//]: # (title: Add / map / remove columns) * [`add`](add.md) columns to [`DataFrame`](DataFrame.md) * [`map`](map.md) columns to new [`DataFrame`](DataFrame.md) or [`DataColumn`](DataColumn.md) diff --git a/docs/StardustDocs/topics/appendDuplicate.md b/docs/StardustDocs/topics/appendDuplicate.md index 48e731fee7..13653e069c 100644 --- a/docs/StardustDocs/topics/appendDuplicate.md +++ b/docs/StardustDocs/topics/appendDuplicate.md @@ -1,4 +1,4 @@ -[//]: # (title: Append/duplicate rows) +[//]: # (title: Append / duplicate rows) * [`append`](append.md) — append new rows * [`duplicate`](duplicate.md) — duplicate selected rows diff --git a/docs/StardustDocs/topics/explodeImplode.md b/docs/StardustDocs/topics/explodeImplode.md index 8e3fb04072..96a20663f4 100644 --- a/docs/StardustDocs/topics/explodeImplode.md +++ b/docs/StardustDocs/topics/explodeImplode.md @@ -1,4 +1,4 @@ -[//]: # (title: Explode/implode columns) +[//]: # (title: Explode / implode columns) * [`explode`](explode.md) — distributes lists of values or [`DataFrames`](DataFrame.md) in given columns vertically, replicating data in other columns * [`implode`](implode.md) — collects column values in given columns into lists or [`DataFrames`](DataFrame.md), grouping by other columns diff --git a/docs/StardustDocs/topics/groupByConcat.md b/docs/StardustDocs/topics/groupByConcat.md index 55dea66b78..267ecc753c 100644 --- a/docs/StardustDocs/topics/groupByConcat.md +++ b/docs/StardustDocs/topics/groupByConcat.md @@ -1,4 +1,4 @@ -[//]: # (title: GroupBy/concat rows) +[//]: # (title: GroupBy / concat rows) * [`groupBy`](groupBy.md) — groups rows of [`DataFrame`](DataFrame.md) by given key columns. * [`concat`](concat.md) — concatenates rows from several [`DataFrames`](DataFrame.md) into single [`DataFrame`](DataFrame.md). diff --git a/docs/StardustDocs/topics/groupUngroupFlatten.md b/docs/StardustDocs/topics/groupUngroupFlatten.md index 5b7ee5a3e0..f31e29bf96 100644 --- a/docs/StardustDocs/topics/groupUngroupFlatten.md +++ b/docs/StardustDocs/topics/groupUngroupFlatten.md @@ -1,4 +1,4 @@ -[//]: # (title: Group/ungroup/flatten columns) +[//]: # (title: Group / ungroup / flatten columns) * [`group`](group.md) — groups given columns into [`ColumnGroups`](DataColumn.md#columngroup). * [`ungroup`](ungroup.md) — ungroups given [`ColumnGroups`](DataColumn.md#columngroup) by replacing them with their children columns diff --git a/docs/StardustDocs/topics/insertReplace.md b/docs/StardustDocs/topics/insertReplace.md index b628a4c249..e8b84318c8 100644 --- a/docs/StardustDocs/topics/insertReplace.md +++ b/docs/StardustDocs/topics/insertReplace.md @@ -1,4 +1,4 @@ -[//]: # (title: Insert/replace columns) +[//]: # (title: Insert / replace columns) * [`insert`](insert.md) — inserts new column into [`DataFrame`](DataFrame.md) * [`replace`](replace.md) — replaces columns in [`DataFrame`](DataFrame.md) diff --git a/docs/StardustDocs/topics/moveRename.md b/docs/StardustDocs/topics/moveRename.md index 9cada9439a..588cfa0e99 100644 --- a/docs/StardustDocs/topics/moveRename.md +++ b/docs/StardustDocs/topics/moveRename.md @@ -1,4 +1,4 @@ -[//]: # (title: Move/rename/reorder columns) +[//]: # (title: Move / rename / reorder columns) * [`move`](move.md) — move columns or change column grouping * [`rename`](rename.md) — rename columns diff --git a/docs/StardustDocs/topics/pivotGather.md b/docs/StardustDocs/topics/pivotGather.md index e5819ecd8b..7dd6963efe 100644 --- a/docs/StardustDocs/topics/pivotGather.md +++ b/docs/StardustDocs/topics/pivotGather.md @@ -1,4 +1,4 @@ -[//]: # (title: Pivot/gather columns) +[//]: # (title: Pivot / gather columns) * [`pivot`](pivot.md) — transforms column values into new columns (long to wide) * [`gather`](gather.md) — collects values from several columns into two `key` and `value` columns (wide to long) diff --git a/docs/StardustDocs/topics/splitMerge.md b/docs/StardustDocs/topics/splitMerge.md index 722f290c74..48dff35e3f 100644 --- a/docs/StardustDocs/topics/splitMerge.md +++ b/docs/StardustDocs/topics/splitMerge.md @@ -1,4 +1,4 @@ -[//]: # (title: Split/merge columns) +[//]: # (title: Split / merge columns) * [`split`](split.md) column values horizontally or vertically * [`merge`](merge.md) values from several columns into single column diff --git a/docs/StardustDocs/topics/updateConvert.md b/docs/StardustDocs/topics/updateConvert.md index 77575b0515..0539cb1b3f 100644 --- a/docs/StardustDocs/topics/updateConvert.md +++ b/docs/StardustDocs/topics/updateConvert.md @@ -1,4 +1,4 @@ -[//]: # (title: Update/convert values) +[//]: # (title: Update / convert values) Both [`update`](update.md) and [`convert`](convert.md) can be used to change columns values in `DataFrame`. From be6ad2a819888c87fa25a0efe3a6db1abdd83221 Mon Sep 17 00:00:00 2001 From: Nikita Klimenko Date: Fri, 19 May 2023 15:01:55 +0300 Subject: [PATCH 41/45] grammar fix --- docs/StardustDocs/topics/updateConvert.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/StardustDocs/topics/updateConvert.md b/docs/StardustDocs/topics/updateConvert.md index 0539cb1b3f..47c5dce7cc 100644 --- a/docs/StardustDocs/topics/updateConvert.md +++ b/docs/StardustDocs/topics/updateConvert.md @@ -1,7 +1,7 @@ [//]: # (title: Update / convert values) -Both [`update`](update.md) and [`convert`](convert.md) can be used to change columns values in `DataFrame`. +Both [`update`](update.md) and [`convert`](convert.md) can be used to change column values in a `DataFrame`. Difference between these operations: -* `convert` allows to change the type of the column, `update` doesn't -* `update` allows to filter cells to be updated, `convert` doesn't +* `convert` allows changing the type of the column, `update` doesn't +* `update` allows filtering cells to be updated, `convert` doesn't From 3e51444e199da1d437b5b906f89f44a7ca1a959e Mon Sep 17 00:00:00 2001 From: Nikita Klimenko Date: Tue, 1 Aug 2023 15:13:34 +0300 Subject: [PATCH 42/45] update generated sources and korro --- .../explainer/PluginCallbackProxy.kt | 2 +- .../kotlinx/dataframe/samples/api/Modify.kt | 71 ++++++++++++++----- ...rame.samples.api.Modify.splitIntoRows.html | 20 +++--- 3 files changed, 66 insertions(+), 27 deletions(-) diff --git a/core/generated-sources/src/test/kotlin/org/jetbrains/kotlinx/dataframe/explainer/PluginCallbackProxy.kt b/core/generated-sources/src/test/kotlin/org/jetbrains/kotlinx/dataframe/explainer/PluginCallbackProxy.kt index c3d34c30ed..8ee639f9e0 100644 --- a/core/generated-sources/src/test/kotlin/org/jetbrains/kotlinx/dataframe/explainer/PluginCallbackProxy.kt +++ b/core/generated-sources/src/test/kotlin/org/jetbrains/kotlinx/dataframe/explainer/PluginCallbackProxy.kt @@ -118,7 +118,7 @@ object PluginCallbackProxy : PluginCallback { body = """
- ${expressions.joinToString(".") { it.source } + ${expressions.joinToSource() .also { if (it.length > 95) TODO("expression is too long ${it.length}. better to split sample in multiple snippets") } diff --git a/core/generated-sources/src/test/kotlin/org/jetbrains/kotlinx/dataframe/samples/api/Modify.kt b/core/generated-sources/src/test/kotlin/org/jetbrains/kotlinx/dataframe/samples/api/Modify.kt index 1a8bf5c505..82d0a081b6 100644 --- a/core/generated-sources/src/test/kotlin/org/jetbrains/kotlinx/dataframe/samples/api/Modify.kt +++ b/core/generated-sources/src/test/kotlin/org/jetbrains/kotlinx/dataframe/samples/api/Modify.kt @@ -469,7 +469,7 @@ class Modify : TestBase() { @TransformDataFrameExpressions fun splitInplace_properties() { // SampleStart - df.split { name.firstName }.by { it.chars().toList() }.inplace() + df.split { name.firstName }.by { it.asIterable() }.inplace() // SampleEnd } @@ -480,7 +480,7 @@ class Modify : TestBase() { val name by columnGroup() val firstName by name.column() - df.split { firstName }.by { it.chars().toList() }.inplace() + df.split { firstName }.by { it.asIterable() }.inplace() // SampleEnd } @@ -488,7 +488,7 @@ class Modify : TestBase() { @TransformDataFrameExpressions fun splitInplace_strings() { // SampleStart - df.split { "name"["firstName"]() }.by { it.chars().toList() }.inplace() + df.split { "name"["firstName"]() }.by { it.asIterable() }.inplace() // SampleEnd } @@ -496,9 +496,7 @@ class Modify : TestBase() { @TransformDataFrameExpressions fun split_properties() { // SampleStart - df.split { name }.by { it.values() }.into("nameParts") - - df.split { name.lastName }.by(" ").default("").inward { "word$it" } + df.split { name.lastName }.by { it.asIterable() }.into("char1", "char2") // SampleEnd } @@ -509,9 +507,7 @@ class Modify : TestBase() { val name by columnGroup() val lastName by name.column() - df.split { name }.by { it.values() }.into("nameParts") - - df.split { lastName }.by(" ").default("").inward { "word$it" } + df.split { lastName }.by { it.asIterable() }.into("char1", "char2") // SampleEnd } @@ -519,18 +515,61 @@ class Modify : TestBase() { @TransformDataFrameExpressions fun split_strings() { // SampleStart - df.split { name }.by { it.values() }.into("nameParts") + df.split { "name"["lastName"]() }.by { it.asIterable() }.into("char1", "char2") + // SampleEnd + } + + @Test + @TransformDataFrameExpressions + fun split1_properties() { + // SampleStart + df.split { name.lastName } + .by { it.asIterable() }.default(' ') + .inward { "char$it" } + // SampleEnd + } + + @Test + @TransformDataFrameExpressions + fun split1_accessors() { + // SampleStart + val name by columnGroup() + val lastName by name.column() - df.split { "name"["lastName"] }.by(" ").default("").inward { "word$it" } + df.split { lastName } + .by { it.asIterable() }.default(' ') + .inward { "char$it" } + // SampleEnd + } + + @Test + @TransformDataFrameExpressions + fun split1_strings() { + // SampleStart + df.split { "name"["lastName"]() } + .by { it.asIterable() }.default(' ') + .inward { "char$it" } // SampleEnd } @Test @TransformDataFrameExpressions fun splitRegex() { - val merged = df.merge { name.lastName and name.firstName }.by { it[0] + " (" + it[1] + ")" }.into("name") - val name by column() // SampleStart + val merged = df.merge { name.lastName and name.firstName } + .by { it[0] + " (" + it[1] + ")" } + .into("name") + // SampleEnd + } + + private val merged = df.merge { name.lastName and name.firstName }.by { it[0] + " (" + it[1] + ")" }.into("name") + + @Test + @TransformDataFrameExpressions + fun splitRegex1() { + // SampleStart + val name by column() + merged.split { name } .match("""(.*) \((.*)\)""") .inward("firstName", "lastName") @@ -562,7 +601,7 @@ class Modify : TestBase() { @TransformDataFrameExpressions fun splitIntoRows_properties() { // SampleStart - df.split { name.firstName }.by { it.chars().toList() }.intoRows() + df.split { name.firstName }.by { it.asIterable() }.intoRows() df.split { name }.by { it.values() }.intoRows() // SampleEnd @@ -575,7 +614,7 @@ class Modify : TestBase() { val name by columnGroup() val firstName by name.column() - df.split { firstName }.by { it.chars().toList() }.intoRows() + df.split { firstName }.by { it.asIterable() }.intoRows() df.split { name }.by { it.values() }.intoRows() // SampleEnd @@ -585,7 +624,7 @@ class Modify : TestBase() { @TransformDataFrameExpressions fun splitIntoRows_strings() { // SampleStart - df.split { "name"["firstName"]() }.by { it.chars().toList() }.intoRows() + df.split { "name"["firstName"]() }.by { it.asIterable() }.intoRows() df.split { colGroup("name") }.by { it.values() }.intoRows() // SampleEnd diff --git a/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.Modify.splitIntoRows.html b/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.Modify.splitIntoRows.html index 3cc292d690..ca02559014 100644 --- a/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.Modify.splitIntoRows.html +++ b/docs/StardustDocs/snippets/org.jetbrains.kotlinx.dataframe.samples.api.Modify.splitIntoRows.html @@ -196,9 +196,9 @@ -
- df.split { name.firstName }.by { it.asIterable() }.intoRows() - +
+ df.split { name.firstName }.by { it.asIterable() }.intoRows() +
Input DataFrame: rowsCount = 7, columnsCount = 5
@@ -223,11 +223,11 @@

... showing only top 20 of 37 rows

-
-
-
- df.split { name }.by { it.values() }.intoRows() - +
+
+
+ df.split { name }.by { it.values() }.intoRows() +
Input DataFrame: rowsCount = 7, columnsCount = 5
@@ -252,8 +252,8 @@

-
-
+
+