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 db289d71ae..b32a594304 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
@@ -35,8 +35,20 @@ internal interface DocumentationUrls {
/** [See Row Expressions on the documentation website.]({@include [Url]}/datarow.html#row-expressions) */
typealias RowExpressions = Nothing
+ /** [See RowExpression on the documentation website.]({@include [Url]}/datarow.html#rowexpression) */
+ typealias RowExpression = Nothing
+
+ /** [See RowValueExpression on the documentation website.]({@include [Url]}/datarow.html#rowvalueexpression) */
+ typealias RowValueExpression = Nothing
+
/** [See Row Conditions on the documentation website.]({@include [Url]}/datarow.html#row-conditions) */
typealias RowConditions = Nothing
+
+ /** [See RowFilter on the documentation website.]({@include [Url]}/datarow.html#rowfilter) */
+ typealias RowFilter = Nothing
+
+ /** [See RowValueFilter on the documentation website.]({@include [Url]}/datarow.html#rowvaluefilter) */
+ typealias RowValueFilter = Nothing
}
/** [See `drop` on the documentation website.]({@include [Url]}/drop.html) */
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 57c5f0f8ad..656f7d8e0f 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
@@ -57,7 +57,11 @@ internal interface ExpressionsGivenRow {
@ExcludeFromSources
typealias AddDataRowNote = Nothing
- /** Provide a new value for every selected cell given its row using a [row expression][DfRowExpression]. */
+ /**
+ * Provide a new value for every selected cell given its row using a [row expression][DfRowExpression].
+ *
+ * Fore more information, {@include [DocumentationUrls.DataRow.RowExpression]}
+ */
interface RowExpression {
/**
@@ -79,6 +83,8 @@ internal interface ExpressionsGivenRow {
/** Provide a new value for every selected cell given its row and its previous value using a
* [row value expression][DfRowValueExpression].
+ *
+ * Fore more information, {@include [DocumentationUrls.DataRow.RowValueExpression]}
*/
interface RowValueExpression {
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 95152ba438..9cbc381db9 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
@@ -41,7 +41,7 @@ internal interface SelectingRows {
* including through [extension properties][AccessApis.ExtensionPropertiesApi]
* for convenient and type-safe access.
*
- * Fore more information, {@include [DocumentationUrls.DataRow.RowConditions]}
+ * Fore more information, {@include [DocumentationUrls.DataRow.RowFilter]}
*/
@ExcludeFromSources
typealias RowFilterSnippet = Nothing
@@ -60,7 +60,7 @@ internal interface SelectingRows {
* including through [extension properties][AccessApis.ExtensionPropertiesApi]
* for convenient and type-safe access.
*
- * Fore more information, {@include [DocumentationUrls.DataRow.RowConditions]}
+ * Fore more information, {@include [DocumentationUrls.DataRow.RowValueFilter]}
*/
@ExcludeFromSources
typealias RowValueFilterSnippet = Nothing
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 d62a56c370..1fe4a54921 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
@@ -265,7 +265,7 @@ internal fun AnyFrame.toHtmlData(
}
val nested = if (col is ColumnGroup<*>) {
col.columns().map {
- col.columnToJs(it.addParentPath(col.path), rowsLimit, configuration, renderRootDf)
+ renderRootDf.columnToJs(it.addParentPath(col.path), rowsLimit, configuration, renderRootDf)
}
} else {
emptyList()
diff --git a/core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/api/format.kt b/core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/api/format.kt
index aebf9b7f18..f700b833fd 100644
--- a/core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/api/format.kt
+++ b/core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/api/format.kt
@@ -11,6 +11,7 @@ import org.jetbrains.kotlinx.dataframe.samples.api.TestBase
import org.jetbrains.kotlinx.dataframe.samples.api.age
import org.jetbrains.kotlinx.dataframe.samples.api.firstName
import org.jetbrains.kotlinx.dataframe.samples.api.isHappy
+import org.jetbrains.kotlinx.dataframe.samples.api.lastName
import org.jetbrains.kotlinx.dataframe.samples.api.name
import org.jetbrains.kotlinx.dataframe.samples.api.weight
import org.junit.Test
@@ -314,6 +315,18 @@ class FormatTests : TestBase() {
formatted::class.simpleName shouldBe "FormattedFrame"
}
+ @Test
+ fun `format with where clause on df with a column group`() {
+ val formatted = df
+ .format { all() }
+ .where { age < 18 }
+ .with { background(red) and textColor(black) }
+
+ val html = formatted.toHtml().toString()
+
+ html.split("background-color:#ff0000").size - 1 shouldBe 7
+ }
+
// Issue #982
@Suppress("ktlint:standard:argument-list-wrapping")
@Test
diff --git a/core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/samples/api/DataRowApi.kt b/core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/samples/api/DataRowApi.kt
deleted file mode 100644
index 7150512478..0000000000
--- a/core/src/test/kotlin/org/jetbrains/kotlinx/dataframe/samples/api/DataRowApi.kt
+++ /dev/null
@@ -1,49 +0,0 @@
-@file:Suppress("ktlint")
-
-package org.jetbrains.kotlinx.dataframe.samples.api
-
-import org.jetbrains.kotlinx.dataframe.api.add
-import org.jetbrains.kotlinx.dataframe.api.at
-import org.jetbrains.kotlinx.dataframe.api.diffOrNull
-import org.jetbrains.kotlinx.dataframe.api.drop
-import org.jetbrains.kotlinx.dataframe.api.filter
-import org.jetbrains.kotlinx.dataframe.api.pivot
-import org.jetbrains.kotlinx.dataframe.api.prev
-import org.jetbrains.kotlinx.dataframe.api.update
-import org.jetbrains.kotlinx.dataframe.api.where
-import org.jetbrains.kotlinx.dataframe.api.with
-import org.jetbrains.kotlinx.dataframe.explainer.TransformDataFrameExpressions
-import org.junit.Test
-
-class DataRowApi : TestBase() {
-
- @Test
- @TransformDataFrameExpressions
- fun expressions() {
- // SampleStart
- // Row expression computes values for a new column
- df.add("fullName") { name.firstName + " " + name.lastName }
-
- // Row expression computes updated values
- df.update { weight }.at(1, 3, 4).with { prev()?.weight }
-
- // Row expression computes cell content for values of pivoted column
- df.pivot { city }.with { name.lastName.uppercase() }
- // SampleEnd
- }
-
- @Test
- @TransformDataFrameExpressions
- fun conditions() {
- // SampleStart
- // Row condition is used to filter rows by index
- df.filter { index() % 5 == 0 }
-
- // Row condition is used to drop rows where `age` is the same as in the previous row
- df.drop { diffOrNull { age } == 0 }
-
- // Row condition is used to filter rows for value update
- df.update { weight }.where { index() > 4 && city != "Paris" }.with { 50 }
- // SampleEnd
- }
-}
diff --git a/docs/StardustDocs/resources/api/dataRowApi/addWithExpression_properties.html b/docs/StardustDocs/resources/api/dataRowApi/addWithExpression_properties.html
new file mode 100644
index 0000000000..6218b8407f
--- /dev/null
+++ b/docs/StardustDocs/resources/api/dataRowApi/addWithExpression_properties.html
@@ -0,0 +1,517 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/StardustDocs/resources/api/dataRowApi/convertExpression_properties.html b/docs/StardustDocs/resources/api/dataRowApi/convertExpression_properties.html
new file mode 100644
index 0000000000..b208982ae8
--- /dev/null
+++ b/docs/StardustDocs/resources/api/dataRowApi/convertExpression_properties.html
@@ -0,0 +1,516 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/StardustDocs/resources/api/dataRowApi/dfDataRow.html b/docs/StardustDocs/resources/api/dataRowApi/dfDataRow.html
new file mode 100644
index 0000000000..bf549bf28c
--- /dev/null
+++ b/docs/StardustDocs/resources/api/dataRowApi/dfDataRow.html
@@ -0,0 +1,516 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/StardustDocs/resources/api/dataRowApi/dropWithCondition_properties.html b/docs/StardustDocs/resources/api/dataRowApi/dropWithCondition_properties.html
new file mode 100644
index 0000000000..fa066e9fdd
--- /dev/null
+++ b/docs/StardustDocs/resources/api/dataRowApi/dropWithCondition_properties.html
@@ -0,0 +1,516 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/StardustDocs/resources/api/dataRowApi/filterWithConditionDf.html b/docs/StardustDocs/resources/api/dataRowApi/filterWithConditionDf.html
new file mode 100644
index 0000000000..29feda83f1
--- /dev/null
+++ b/docs/StardustDocs/resources/api/dataRowApi/filterWithConditionDf.html
@@ -0,0 +1,516 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/StardustDocs/resources/api/dataRowApi/filterWithCondition_properties.html b/docs/StardustDocs/resources/api/dataRowApi/filterWithCondition_properties.html
new file mode 100644
index 0000000000..ba45b38a2e
--- /dev/null
+++ b/docs/StardustDocs/resources/api/dataRowApi/filterWithCondition_properties.html
@@ -0,0 +1,516 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/StardustDocs/resources/api/dataRowApi/firstWithCondition_properties.html b/docs/StardustDocs/resources/api/dataRowApi/firstWithCondition_properties.html
new file mode 100644
index 0000000000..ef1235876d
--- /dev/null
+++ b/docs/StardustDocs/resources/api/dataRowApi/firstWithCondition_properties.html
@@ -0,0 +1,516 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/StardustDocs/resources/api/dataRowApi/formatWithCondition_properties.html b/docs/StardustDocs/resources/api/dataRowApi/formatWithCondition_properties.html
new file mode 100644
index 0000000000..ef126227e1
--- /dev/null
+++ b/docs/StardustDocs/resources/api/dataRowApi/formatWithCondition_properties.html
@@ -0,0 +1,516 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/StardustDocs/resources/api/dataRowApi/gatherWithCondition_properties.html b/docs/StardustDocs/resources/api/dataRowApi/gatherWithCondition_properties.html
new file mode 100644
index 0000000000..3634a854ec
--- /dev/null
+++ b/docs/StardustDocs/resources/api/dataRowApi/gatherWithCondition_properties.html
@@ -0,0 +1,514 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/StardustDocs/resources/api/dataRowApi/pivotWithExpression_properties.html b/docs/StardustDocs/resources/api/dataRowApi/pivotWithExpression_properties.html
new file mode 100644
index 0000000000..0895649dc5
--- /dev/null
+++ b/docs/StardustDocs/resources/api/dataRowApi/pivotWithExpression_properties.html
@@ -0,0 +1,515 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/StardustDocs/resources/api/dataRowApi/updateWithCondition_properties.html b/docs/StardustDocs/resources/api/dataRowApi/updateWithCondition_properties.html
new file mode 100644
index 0000000000..0f4440d85f
--- /dev/null
+++ b/docs/StardustDocs/resources/api/dataRowApi/updateWithCondition_properties.html
@@ -0,0 +1,516 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/StardustDocs/resources/api/dataRowApi/updateWithExpression_properties.html b/docs/StardustDocs/resources/api/dataRowApi/updateWithExpression_properties.html
new file mode 100644
index 0000000000..b32d21abb9
--- /dev/null
+++ b/docs/StardustDocs/resources/api/dataRowApi/updateWithExpression_properties.html
@@ -0,0 +1,516 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/StardustDocs/resources/api/groupBy/pivotOnGroupBy_properties.html b/docs/StardustDocs/resources/api/groupBy/pivotOnGroupBy_properties.html
index ee2e423717..04e742cb72 100644
--- a/docs/StardustDocs/resources/api/groupBy/pivotOnGroupBy_properties.html
+++ b/docs/StardustDocs/resources/api/groupBy/pivotOnGroupBy_properties.html
@@ -461,7 +461,7 @@
{ name: "\">Alice", children: [], rightAlign: false, values: [{ frameId: 1, value: "DataFrame 1 x 5" },{ frameId: 2, value: "DataFrame 2 x 5" }] },
{ name: "\">Bob", children: [], rightAlign: false, values: [{ frameId: 3, value: "DataFrame 2 x 5" },{ frameId: 4, value: "DataFrame 1 x 5" }] },
{ name: "\">Charlie", children: [], rightAlign: false, values: [{ frameId: 5, value: "DataFrame 2 x 5" },{ frameId: 6, value: "DataFrame 2 x 5" }] },
-{ name: "\">firstName", children: [1, 2, 3], rightAlign: false, values: ["{ Alice: DataFrame [1 x 5], B..., C... }","{ Alice: DataFrame [2 x 5], B..., C... }"] },
+{ name: "\">firstName", children: [1, 2, 3], rightAlign: false, values: ["{ Alice: DataFrame [1 x 5], B..., C... }","{ Alice: DataFrame [2 x 5], B..., C... }"] },
{ name: "\">name", children: [4], rightAlign: false, values: ["{ firstName: { Alice: DataFr..., ... } }","{ firstName: { Alice: DataFr..., ... } }"] },
], id: 0, rootId: 0, totalRows: 2 } ) });
/*-->*/
diff --git a/docs/StardustDocs/resources/api/pivot/pivotAnd_properties.html b/docs/StardustDocs/resources/api/pivot/pivotAnd_properties.html
index 118973967c..119d8b05a0 100644
--- a/docs/StardustDocs/resources/api/pivot/pivotAnd_properties.html
+++ b/docs/StardustDocs/resources/api/pivot/pivotAnd_properties.html
@@ -459,11 +459,11 @@
/**/
diff --git a/docs/StardustDocs/resources/api/pivot/pivotGroupByFrames_properties.html b/docs/StardustDocs/resources/api/pivot/pivotGroupByFrames_properties.html
index c9d99d5091..161cbaeb5b 100644
--- a/docs/StardustDocs/resources/api/pivot/pivotGroupByFrames_properties.html
+++ b/docs/StardustDocs/resources/api/pivot/pivotGroupByFrames_properties.html
@@ -460,7 +460,7 @@
call_DataFrame(function() { DataFrame.addTable({ cols: [{ name: "firstName", children: [], rightAlign: false, values: ["Alice","Bob","Charlie"] },
{ name: "\">true", children: [], rightAlign: false, values: [{ frameId: 1, value: "DataFrame 1 x 5" },{ frameId: 2, value: "DataFrame 2 x 5" },{ frameId: 3, value: "DataFrame 2 x 5" }] },
{ name: "\">false", children: [], rightAlign: false, values: [{ frameId: 4, value: "DataFrame 2 x 5" },{ frameId: 5, value: "DataFrame 1 x 5" },{ frameId: 6, value: "DataFrame 2 x 5" }] },
-{ name: "\">isHappy", children: [1, 2], rightAlign: false, values: ["{ true: DataFrame [1 x 5], false: D... }","{ true: DataFrame [2 x 5], false: D... }","{ true: DataFrame [2 x 5], false: D... }"] },
+{ name: "\">isHappy", children: [1, 2], rightAlign: false, values: ["{ true: DataFrame [1 x 5], false: D... }","{ true: DataFrame [2 x 5], false: D... }","{ true: DataFrame [2 x 5], false: D... }"] },
], id: 0, rootId: 0, totalRows: 3 } ) });
/*-->*/
diff --git a/docs/StardustDocs/resources/api/pivot/pivotGroupByOther_properties.html b/docs/StardustDocs/resources/api/pivot/pivotGroupByOther_properties.html
index 9d25492087..efd54781e5 100644
--- a/docs/StardustDocs/resources/api/pivot/pivotGroupByOther_properties.html
+++ b/docs/StardustDocs/resources/api/pivot/pivotGroupByOther_properties.html
@@ -465,7 +465,7 @@
{ name: "weight", children: [], rightAlign: true, values: ["54","87","null","null","68","55","90","52","60","70"] },
{ name: "\">true", children: [], rightAlign: false, values: [{ frameId: 1, value: "DataFrame 1 x 5" },{ frameId: 2, value: "DataFrame 1 x 5" },"",{ frameId: 3, value: "DataFrame 1 x 5" },{ frameId: 4, value: "DataFrame 1 x 5" },"",{ frameId: 5, value: "DataFrame 1 x 5" },"","",""] },
{ name: "\">false", children: [], rightAlign: false, values: ["","",{ frameId: 6, value: "DataFrame 1 x 5" },"","",{ frameId: 7, value: "DataFrame 1 x 5" },"",{ frameId: 8, value: "DataFrame 1 x 5" },{ frameId: 9, value: "DataFrame 1 x 5" },{ frameId: 10, value: "DataFrame 1 x 5" }] },
-{ name: "\">isHappy", children: [6, 7], rightAlign: false, values: ["{ true: DataFrame [1 x 5], false: D... }","{ true: DataFrame [1 x 5], false: D... }","{ true: DataFrame [0 x 0], false: D... }","{ true: DataFrame [1 x 5], false: D... }","{ true: DataFrame [1 x 5], false: D... }","{ true: DataFrame [0 x 0], false: D... }","{ true: DataFrame [1 x 5], false: D... }","{ true: DataFrame [0 x 0], false: D... }","{ true: DataFrame [0 x 0], false: D... }","{ true: DataFrame [0 x 0], false: D... }"] },
+{ name: "\">isHappy", children: [6, 7], rightAlign: false, values: ["{ true: DataFrame [1 x 5], false: D... }","{ true: DataFrame [1 x 5], false: D... }","{ true: DataFrame [0 x 0], false: D... }","{ true: DataFrame [1 x 5], false: D... }","{ true: DataFrame [1 x 5], false: D... }","{ true: DataFrame [0 x 0], false: D... }","{ true: DataFrame [1 x 5], false: D... }","{ true: DataFrame [0 x 0], false: D... }","{ true: DataFrame [0 x 0], false: D... }","{ true: DataFrame [0 x 0], false: D... }"] },
], id: 0, rootId: 0, totalRows: 10 } ) });
/*-->*/
diff --git a/docs/StardustDocs/resources/api/pivot/pivotGroupBy_properties.html b/docs/StardustDocs/resources/api/pivot/pivotGroupBy_properties.html
index c9d99d5091..161cbaeb5b 100644
--- a/docs/StardustDocs/resources/api/pivot/pivotGroupBy_properties.html
+++ b/docs/StardustDocs/resources/api/pivot/pivotGroupBy_properties.html
@@ -460,7 +460,7 @@
call_DataFrame(function() { DataFrame.addTable({ cols: [{ name: "firstName", children: [], rightAlign: false, values: ["Alice","Bob","Charlie"] },
{ name: "\">true", children: [], rightAlign: false, values: [{ frameId: 1, value: "DataFrame 1 x 5" },{ frameId: 2, value: "DataFrame 2 x 5" },{ frameId: 3, value: "DataFrame 2 x 5" }] },
{ name: "\">false", children: [], rightAlign: false, values: [{ frameId: 4, value: "DataFrame 2 x 5" },{ frameId: 5, value: "DataFrame 1 x 5" },{ frameId: 6, value: "DataFrame 2 x 5" }] },
-{ name: "\">isHappy", children: [1, 2], rightAlign: false, values: ["{ true: DataFrame [1 x 5], false: D... }","{ true: DataFrame [2 x 5], false: D... }","{ true: DataFrame [2 x 5], false: D... }"] },
+{ name: "\">isHappy", children: [1, 2], rightAlign: false, values: ["{ true: DataFrame [1 x 5], false: D... }","{ true: DataFrame [2 x 5], false: D... }","{ true: DataFrame [2 x 5], false: D... }"] },
], id: 0, rootId: 0, totalRows: 3 } ) });
/*-->*/
diff --git a/docs/StardustDocs/resources/api/pivot/pivotInward_properties.html b/docs/StardustDocs/resources/api/pivot/pivotInward_properties.html
index 8ff674999f..274f7cc266 100644
--- a/docs/StardustDocs/resources/api/pivot/pivotInward_properties.html
+++ b/docs/StardustDocs/resources/api/pivot/pivotInward_properties.html
@@ -459,7 +459,7 @@
/**/
diff --git a/docs/StardustDocs/resources/api/pivot/pivotThen_properties.html b/docs/StardustDocs/resources/api/pivot/pivotThen_properties.html
index 3fd5305149..c999da6594 100644
--- a/docs/StardustDocs/resources/api/pivot/pivotThen_properties.html
+++ b/docs/StardustDocs/resources/api/pivot/pivotThen_properties.html
@@ -460,11 +460,11 @@
call_DataFrame(function() { DataFrame.addTable({ cols: [{ name: "\">Alice", children: [], rightAlign: false, values: [{ frameId: 1, value: "DataFrame 1 x 5" }] },
{ name: "\">Bob", children: [], rightAlign: false, values: [{ frameId: 2, value: "DataFrame 2 x 5" }] },
{ name: "\">Charlie", children: [], rightAlign: false, values: [{ frameId: 3, value: "DataFrame 2 x 5" }] },
-{ name: "\">true", children: [0, 1, 2], rightAlign: false, values: ["{ Alice: DataFrame [1 x 5], B..., C... }"] },
+{ name: "\">true", children: [0, 1, 2], rightAlign: false, values: ["{ Alice: DataFrame [1 x 5], B..., C... }"] },
{ name: "\">Charlie", children: [], rightAlign: false, values: [{ frameId: 4, value: "DataFrame 2 x 5" }] },
{ name: "\">Alice", children: [], rightAlign: false, values: [{ frameId: 5, value: "DataFrame 2 x 5" }] },
{ name: "\">Bob", children: [], rightAlign: false, values: [{ frameId: 6, value: "DataFrame 1 x 5" }] },
-{ name: "\">false", children: [4, 5, 6], rightAlign: false, values: ["{ Charlie: DataFrame [2 x 5], ... }"] },
+{ name: "\">false", children: [4, 5, 6], rightAlign: false, values: ["{ Charlie: DataFrame [2 x 5], ... }"] },
], id: 0, rootId: 0, totalRows: 1 } ) });
/*-->*/
diff --git a/docs/StardustDocs/resources/snippets/org.jetbrains.kotlinx.dataframe.samples.api.DataRowApi.conditions.html b/docs/StardustDocs/resources/snippets/org.jetbrains.kotlinx.dataframe.samples.api.DataRowApi.conditions.html
deleted file mode 100644
index 46db5c8bd2..0000000000
--- a/docs/StardustDocs/resources/snippets/org.jetbrains.kotlinx.dataframe.samples.api.DataRowApi.conditions.html
+++ /dev/null
@@ -1,725 +0,0 @@
-
-
-
-
-
-
- df.filter { index() % 5 == 0 }
-
- Input DataFrame: rowsCount = 7, columnsCount = 5
-
-
-
-
-
- Output DataFrame: rowsCount = 2, columnsCount = 5
-
-
-
-
-
-
-
- df.drop { diffOrNull { age } == 0 }
-
- Input DataFrame: rowsCount = 7, columnsCount = 5
-
-
-
-
-
- Output DataFrame: rowsCount = 7, columnsCount = 5
-
-
-
-
-
-
-
- df.update { weight }.where { index() > 4 && city != "Paris" }.with { 5...
-
- Input DataFrame: rowsCount = 7, columnsCount = 5
-
-
-
-
-
- Step 1: Update
-
-
-DataFrame [7 x 5]
-
-
- Step 2: Update
-
-
-DataFrame [7 x 5]
-
-
- Output DataFrame: rowsCount = 7, columnsCount = 5
-
-
-
-
-
-
-
-
-
diff --git a/docs/StardustDocs/resources/snippets/org.jetbrains.kotlinx.dataframe.samples.api.DataRowApi.expressions.html b/docs/StardustDocs/resources/snippets/org.jetbrains.kotlinx.dataframe.samples.api.DataRowApi.expressions.html
deleted file mode 100644
index 5bdff76103..0000000000
--- a/docs/StardustDocs/resources/snippets/org.jetbrains.kotlinx.dataframe.samples.api.DataRowApi.expressions.html
+++ /dev/null
@@ -1,809 +0,0 @@
-
-
-
-
-
-
- df.add("fullName") { name.firstName + " " + name.lastName }
-
- Input DataFrame: rowsCount = 7, columnsCount = 5
-
-
-
-
-
- Output DataFrame: rowsCount = 7, columnsCount = 6
-
-
-
-
-
-
-
- df.update { weight }.at(1, 3, 4).with { prev()?.weight }
-
- Input DataFrame: rowsCount = 7, columnsCount = 5
-
-
-
-
-
- Step 1: Update
-
-
-DataFrame [7 x 5]
-
-
- Step 2: Update
-
-
-DataFrame [7 x 5]
-
-
- Output DataFrame: rowsCount = 7, columnsCount = 5
-
-
-
-
-
-
-
- df.pivot { city }.with { name.lastName.uppercase() }
-
- Input DataFrame: rowsCount = 7, columnsCount = 5
-
-
-
-
-
- Step 1: Pivot
-
-
-
-
-
- Output DataRow
-
-
-
-
-
-
-
-
-
diff --git a/docs/StardustDocs/topics/_shadow_resources.md b/docs/StardustDocs/topics/_shadow_resources.md
index e000fc5e0e..c0d1767fb2 100644
--- a/docs/StardustDocs/topics/_shadow_resources.md
+++ b/docs/StardustDocs/topics/_shadow_resources.md
@@ -326,3 +326,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/StardustDocs/topics/concepts/DataRow.md b/docs/StardustDocs/topics/concepts/DataRow.md
index 8249bba53b..ca4d36a9a3 100644
--- a/docs/StardustDocs/topics/concepts/DataRow.md
+++ b/docs/StardustDocs/topics/concepts/DataRow.md
@@ -1,5 +1,5 @@
[//]: # (title: DataRow)
-
+
`DataRow` represents a single record, one piece of data within a [`DataFrame`](DataFrame.md)
@@ -7,76 +7,375 @@
-* `index(): Int` — sequential row number in [`DataFrame`](DataFrame.md), starts from 0
-* `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 [`DataFrame`](DataFrame.md) objects 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
-* `columnNames(): List` — list of all column names
-* `columnTypes(): List` — list of all column types
-* `namedValues(): List>` — list of name-value pairs where `name` is a column name and `value` is cell value
-* `namedValuesOf(): List>` — list of name-value pairs where value has given type
-* `transpose(): DataFrame>` — [`DataFrame`](DataFrame.md) of two columns: `name: String` is column names and `value: Any?` is cell values
-* `transposeTo(): DataFrame>`— [`DataFrame`](DataFrame.md) of two columns: `name: String` is column names and `value: T` is cell values
-* `getRow(Int): DataRow` — row from [`DataFrame`](DataFrame.md) by row index
-* `getRows(Iterable): DataFrame` — [`DataFrame`](DataFrame.md) with subset of rows selected by absolute row index.
-* `relative(Iterable): DataFrame` — [`DataFrame`](DataFrame.md) 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
+* `index(): Int` — sequential row number in [`DataFrame`](DataFrame.md), starts from 0;
+* `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 the current and previous rows;
+* `explode(columns): DataFrame` — spread lists and [`DataFrame`](DataFrame.md) objects 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;
+* `columnNames(): List` — list of all column names;
+* `columnTypes(): List` — list of all column types;
+* `namedValues(): List>` — list of name-value pairs where `name` is a column name
+and `value` is a cell value;
+* `namedValuesOf(): List>` — list of name-value pairs where the value has the given type;
+* `transpose(): DataFrame>` — [`DataFrame`](DataFrame.md) with two columns: `name: String` for column names
+and `value: Any?` for cell values;
+* `transposeTo(): DataFrame>` — [`DataFrame`](DataFrame.md) with two columns: `name: String` for column names
+and `value: T` for cell values;
+* `getRow(Int): DataRow` — row from the [`DataFrame`](DataFrame.md) by a row index;
+* `getRows(Iterable): DataFrame` — [`DataFrame`](DataFrame.md) with a subset of rows selected by absolute row indices;
+* `relative(Iterable): DataFrame` — [`DataFrame`](DataFrame.md) with a subset of rows selected by relative row indices:
+`relative(-1..1)` will return the 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 the given `columnName`;
+* `getValueOrNull(columnName)` — cell value of type `T?` by this row
+and the given `columnName` or `null` if there's no such column;
+* `get(column): T` — cell value by this row and the given `column`;
+* `String.invoke(): T` — cell value of type `T` by this row and the given `this` column name;
+* `ColumnPath.invoke(): T` — cell value of type `T` by this row and the given `this` column path;
+* `ColumnReference.invoke(): T` — cell value of type `T` by this row and the given `this` column;
+* `df()` — [`DataFrame`](DataFrame.md) that the current row belongs to.
+The following dataframe will be used in the examples below:
+
+
+
+```kotlin
+df
+```
+
+
+
+
## Row expressions
-Row expressions provide a value for every row of [`DataFrame`](DataFrame.md) and are used in [add](add.md), [filter](filter.md), [forEach](iterate.md), [update](update.md) and other operations.
+Row expressions provide a value for every row of [`DataFrame`](DataFrame.md)
+and are used in [add](add.md), [filter](filter.md), [forEach](iterate.md), [update](update.md), and other operations.
+There are two types of row expressions, differing in what the `it` argument refers to:
+
+### `RowExpression`
+`RowExpression` computes a new value for every selected cell given the [`DataRow`](DataRow.md) of that cell.
+Both `this` and `it` keywords in `RowExpression` refer to the same [`DataRow`](DataRow.md).
+Row values can be accessed with or without these keywords.
-
+`RowExpression` signature: ```DataRow.(DataRow) -> T```.
+
+#### `RowExpression` examples
+
+##### add {collapsible="true"}
+
+
+
+
```kotlin
// Row expression computes values for a new column
df.add("fullName") { name.firstName + " " + name.lastName }
+```
+
+
+
+
+```kotlin
+// Row expression computes values for a new column
+df.add("fullName") { "name"["firstName"] + " " + "name"["lastName"] }
+```
+
+
+
+
+
+##### pivot {collapsible="true"}
-// Row expression computes updated values
-df.update { weight }.at(1, 3, 4).with { prev()?.weight }
+
+
+
+```kotlin
// Row expression computes cell content for values of pivoted column
df.pivot { city }.with { name.lastName.uppercase() }
```
-
+
+
+
+```kotlin
+// Row expression computes cell content for values of pivoted column
+df.pivot { city }.with { "name"["lastName"]().uppercase() }
+```
+
+
+
+
+
+### `RowValueExpression`
+`RowValueExpression` computes a new value for every selected cell given the [`DataRow`](DataRow.md) of that cell
+and the current value of that cell. `this` refers to the current [`DataRow`](DataRow.md),
+and `it` refers to the current value of the cell.
+`RowValueExpression` is used after selecting columns in functions such as [`update`](update.md) or [`convert`](convert.md).
+
+`RowValueExpression` signature: ```DataRow.(C) -> T```.
+
+#### `RowValueExpression` examples
+
+##### update (expression) {collapsible="true"}
+
+
+
+
+
+```kotlin
+// "it" refers to the current "weight" cell, and "prev()" is called on the row "this"
+df.update { weight }.at(2, 3, 5).with { it ?: prev()?.weight }
+```
+
+
+
+
+```kotlin
+// "it" refers to the current "weight" cell, and "prev()" is called on the row "this"
+df.update("weight").at(2, 3, 5).with { it ?: prev()?.get("weight") }
+```
+
+
+
+
+##### convert {collapsible="true"}
+
+
+
+
+```kotlin
+// "it" refers to the current "city" cell
+df.convert { city }.notNull { it.uppercase() }
+```
+
+
+
+
+```kotlin
+// "it" refers to the current "city" cell
+df.convert("city").notNull { (it as String).uppercase() }
+```
-Row expression signature: ```DataRow.(DataRow) -> T```. Row values can be accessed with or without ```it``` keyword. Implicit and explicit argument represent the same `DataRow` object.
+
+
+
## Row conditions
-Row condition is a special case of [row expression](#row-expressions) that returns `Boolean`.
+Row condition is a special case of [row expression](#row-expressions) that returns `Boolean`.
+There are two types of row conditions:
+
+### `RowFilter`
+`RowFilter` evaluates a [`DataRow`](DataRow.md)
+and returns a `Boolean` indicating whether the row should be included in the result.
+Both `this` and `it` in `RowFilter` refer to the same [`DataRow`](DataRow.md).
+`RowFilter` is used in functions such as [`filter`](filter.md), [`drop`](drop.md),
+[`first`](first.md), and [`count`](count.md).
+
+`RowFilter` signature: ```DataRow.(DataRow) -> Boolean```.
+
+#### `RowFilter` examples
+
+##### filter {collapsible="true"}
+
+
+
+```kotlin
+df
+```
+
+
+
-
+
+
+
```kotlin
-// Row condition is used to filter rows by index
-df.filter { index() % 5 == 0 }
+// Row filter is used to filter rows
+df.filter { name.firstName == "Alice" && age >= 18 }
+```
-// Row condition is used to drop rows where `age` is the same as in the previous row
-df.drop { diffOrNull { age } == 0 }
+
+
-// Row condition is used to filter rows for value update
-df.update { weight }.where { index() > 4 && city != "Paris" }.with { 50 }
+```kotlin
+// Row filter is used to filter rows
+df.filter { "name"["firstName"]() == "Alice" && "age"() >= 18 }
```
-
+
+
+
+##### drop {collapsible="true"}
-Row condition signature: ```DataRow.(DataRow) -> Boolean```
+
+
+
+```kotlin
+// Row filter is used to drop rows where `city` or `weight` is null
+df.drop { city == null || weight == null }
+```
+
+
+
+```kotlin
+// Row filter is used to drop rows where `city` or `weight` is null
+df.drop { "city"() == null || "weight"() == null }
+```
+
+
+
+
+
+##### first {collapsible="true"}
+
+
+
+
+
+```kotlin
+// Row filter is used to take the first row where `city` is Milan
+df.first { city == "Milan" }
+```
+
+
+
+
+```kotlin
+// Row filter is used to take the first row where `city` is Milan
+df.first { "city"() == "Milan" }
+```
+
+
+
+
+
+##### count {collapsible="true"}
+
+
+
+
+
+```kotlin
+// Row filter is used to count happy people
+df.count { isHappy } // the result is 5
+```
+
+
+
+
+```kotlin
+// Row filter is used to count happy people
+df.count { "isHappy"() } // the result is 5
+```
+
+
+
+
+### `RowValueFilter`
+`RowValueFilter` is used after selecting columns in functions
+such as [`update`](update.md), [`gather`](gather.md), and [`format`](format.md).
+Like `RowFilter`, it returns a `Boolean` indicating whether the row should be included in the result.
+However, unlike `RowFilter`, where both `this` and `it` refer to the current [`DataRow`](DataRow.md),
+`RowValueFilter` uses the current row as `this` and can also access the selected column value from this row as `it`.
+
+`RowValueFilter` signature: ```DataRow.(C) -> Boolean```.
+
+#### `RowValueFilter` examples
+
+##### update (condition) {collapsible="true"}
+
+
+
+
+
+```kotlin
+// Row value filter is used to filter rows for value update
+df.update { age }.where { name.firstName == "Alice" && name.lastName == "Cooper" }.with { 16 }
+```
+
+
+
+
+```kotlin
+// Row value filter is used to filter rows for value update
+df.update("age")
+ .where {
+ "name"["firstName"]() == "Alice" &&
+ "name"["lastName"]() == "Cooper"
+ }
+ .with { 16 }
+```
+
+
+
+
+
+##### gather {collapsible="true"}
+
+
+
+
+
+```kotlin
+// Row value filter is used to gather only unfilled profile fields
+df.gather { age and city and weight and isHappy }
+ .where { it == null }
+ .into("field", "value")
+```
+
+
+
+
+```kotlin
+// Row value filter is used to gather only unfilled profile fields
+df.gather("age", "city", "weight", "isHappy")
+ .where { it == null }
+ .into("field", "value")
+```
+
+
+
+
+
+##### format {collapsible="true"}
+
+
+
+
+
+```kotlin
+// Row value filter is used to format only rows with minors
+df
+ .format()
+ .where { age < 18 }
+ .with { background(RgbColor(242, 210, 189)) and textColor(black) }
+```
+
+
+
+
+```kotlin
+// Row value filter is used to format only rows with minors
+df
+ .format()
+ .where { "age"() < 18 }
+ .with { background(RgbColor(242, 210, 189)) and textColor(black) }
+```
+
+
+
+
## Row statistics
@@ -91,7 +390,7 @@ These statistics will be applied only to values of appropriate types, and incomp
For example, if a [dataframe](DataFrame.md) has columns of types `String` and `Int`,
`rowSum()` will compute the sum of the `Int` values in the row and ignore `String` values.
-To apply statistics only to values of a particular type use `-Of` versions:
+To apply statistics only to values of a particular type, use `-Of` versions:
* `rowSumOf`
* `rowMeanOf`
* `rowStdOf`
diff --git a/samples/src/test/kotlin/org/jetbrains/kotlinx/dataframe/samples/api/DataRowApiSamples.kt b/samples/src/test/kotlin/org/jetbrains/kotlinx/dataframe/samples/api/DataRowApiSamples.kt
new file mode 100644
index 0000000000..6cf4916f7d
--- /dev/null
+++ b/samples/src/test/kotlin/org/jetbrains/kotlinx/dataframe/samples/api/DataRowApiSamples.kt
@@ -0,0 +1,292 @@
+package org.jetbrains.kotlinx.dataframe.samples.api
+
+import org.jetbrains.kotlinx.dataframe.api.RgbColor
+import org.jetbrains.kotlinx.dataframe.api.add
+import org.jetbrains.kotlinx.dataframe.api.and
+import org.jetbrains.kotlinx.dataframe.api.at
+import org.jetbrains.kotlinx.dataframe.api.convert
+import org.jetbrains.kotlinx.dataframe.api.count
+import org.jetbrains.kotlinx.dataframe.api.drop
+import org.jetbrains.kotlinx.dataframe.api.filter
+import org.jetbrains.kotlinx.dataframe.api.first
+import org.jetbrains.kotlinx.dataframe.api.format
+import org.jetbrains.kotlinx.dataframe.api.gather
+import org.jetbrains.kotlinx.dataframe.api.into
+import org.jetbrains.kotlinx.dataframe.api.notNull
+import org.jetbrains.kotlinx.dataframe.api.perRowCol
+import org.jetbrains.kotlinx.dataframe.api.pivot
+import org.jetbrains.kotlinx.dataframe.api.prev
+import org.jetbrains.kotlinx.dataframe.api.toDataFrame
+import org.jetbrains.kotlinx.dataframe.api.update
+import org.jetbrains.kotlinx.dataframe.api.where
+import org.jetbrains.kotlinx.dataframe.api.with
+import org.jetbrains.kotlinx.dataframe.samples.DataFrameSampleHelper
+import org.jetbrains.kotlinx.dataframe.util.defaultHeaderFormatting
+import org.junit.Test
+
+class DataRowApiSamples : DataFrameSampleHelper("dataRowApi", "api") {
+ private val df = peopleDf
+
+ private fun lastNameToColorUpdateCondition(name: String): RgbColor? =
+ when (name) {
+ "Cooper" -> RgbColor(189, 206, 233)
+ else -> null
+ }
+
+ private fun lastNameToColorUpdateExpression(name: String): RgbColor? =
+ when (name) {
+ "Daniels" -> RgbColor(189, 206, 233)
+ "Chaplin" -> RgbColor(242, 210, 189)
+ "Wolf" -> RgbColor(233, 199, 220)
+ else -> null
+ }
+
+ private fun lastNameToColorFilter(name: String): RgbColor? =
+ when (name) {
+ "Wolf" -> RgbColor(242, 210, 189)
+ "Smith" -> RgbColor(233, 199, 220)
+ else -> null
+ }
+
+ @Test
+ fun dfDataRow() {
+ // SampleStart
+ df
+ // SampleEnd
+ .saveDfHtmlSample()
+ }
+
+ @Test
+ fun addWithExpression_properties() {
+ // SampleStart
+ // Row expression computes values for a new column
+ df.add("fullName") { name.firstName + " " + name.lastName }
+ // SampleEnd
+ .defaultHeaderFormatting { fullName }
+ .saveDfHtmlSample()
+ }
+
+ @Test
+ fun addWithExpression_strings() {
+ // SampleStart
+ // Row expression computes values for a new column
+ df.add("fullName") { "name"["firstName"] + " " + "name"["lastName"] }
+ // SampleEnd
+ }
+
+ @Test
+ fun updateWithExpression_properties() {
+ // SampleStart
+ // "it" refers to the current "weight" cell, and "prev()" is called on the row "this"
+ df.update { weight }.at(2, 3, 5).with { it ?: prev()?.weight }
+ // SampleEnd
+ .format().perRowCol { row, _ ->
+ val lastName = df[row.index()].name.lastName
+ lastNameToColorUpdateExpression(lastName)?.let { color ->
+ background(color) and textColor(black)
+ }
+ }
+ .saveDfHtmlSample()
+ }
+
+ @Test
+ fun updateWithExpression_strings() {
+ // SampleStart
+ // "it" refers to the current "weight" cell, and "prev()" is called on the row "this"
+ df.update("weight").at(2, 3, 5).with { it ?: prev()?.get("weight") }
+ // SampleEnd
+ }
+
+ @Test
+ fun convertExpression_properties() {
+ // SampleStart
+ // "it" refers to the current "city" cell
+ df.convert { city }.notNull { it.uppercase() }
+ // SampleEnd
+ .saveDfHtmlSample()
+ }
+
+ @Test
+ fun convertExpression_strings() {
+ // SampleStart
+ // "it" refers to the current "city" cell
+ df.convert("city").notNull { (it as String).uppercase() }
+ // SampleEnd
+ }
+
+ @Test
+ fun pivotWithExpression_properties() {
+ // SampleStart
+ // Row expression computes cell content for values of pivoted column
+ df.pivot { city }.with { name.lastName.uppercase() }
+ // SampleEnd
+ .toDataFrame()
+ .saveDfHtmlSample()
+ }
+
+ @Test
+ fun pivotWithExpression_strings() {
+ // SampleStart
+ // Row expression computes cell content for values of pivoted column
+ df.pivot { city }.with { "name"["lastName"]().uppercase() }
+ // SampleEnd
+ }
+
+ @Test
+ fun filterWithConditionDf() {
+ df.format().perRowCol { row, _ ->
+ val lastName = row.name.lastName
+ lastNameToColorFilter(lastName)?.let { color ->
+ background(color) and textColor(black)
+ }
+ }
+ .saveDfHtmlSample()
+ }
+
+ @Test
+ fun filterWithCondition_properties() {
+ // SampleStart
+ // Row filter is used to filter rows
+ df.filter { name.firstName == "Alice" && age >= 18 }
+ // SampleEnd
+ .format().perRowCol { row, _ ->
+ val lastName = row.name.lastName
+ lastNameToColorFilter(lastName)?.let { color ->
+ background(color) and textColor(black)
+ }
+ }
+ .saveDfHtmlSample()
+ }
+
+ @Test
+ fun filterWithCondition_strings() {
+ // SampleStart
+ // Row filter is used to filter rows
+ df.filter { "name"["firstName"]() == "Alice" && "age"() >= 18 }
+ // SampleEnd
+ }
+
+ @Test
+ fun dropWithCondition_properties() {
+ // SampleStart
+ // Row filter is used to drop rows where `city` or `weight` is null
+ df.drop { city == null || weight == null }
+ // SampleEnd
+ .saveDfHtmlSample()
+ }
+
+ @Test
+ fun dropWithCondition_strings() {
+ // SampleStart
+ // Row filter is used to drop rows where `city` or `weight` is null
+ df.drop { "city"() == null || "weight"() == null }
+ // SampleEnd
+ }
+
+ @Test
+ fun firstWithCondition_properties() {
+ // SampleStart
+ // Row filter is used to take the first row where `city` is Milan
+ df.first { city == "Milan" }
+ // SampleEnd
+ .toDataFrame()
+ .saveDfHtmlSample()
+ }
+
+ @Test
+ fun firstWithCondition_strings() {
+ // SampleStart
+ // Row filter is used to take the first row where `city` is Milan
+ df.first { "city"() == "Milan" }
+ // SampleEnd
+ }
+
+ @Test
+ fun countWithCondition_properties() {
+ // SampleStart
+ // Row filter is used to count happy people
+ df.count { isHappy } // the result is 5
+ // SampleEnd
+ }
+
+ @Test
+ fun countWithCondition_strings() {
+ // SampleStart
+ // Row filter is used to count happy people
+ df.count { "isHappy"() } // the result is 5
+ // SampleEnd
+ }
+
+ @Test
+ fun updateWithCondition_properties() {
+ // SampleStart
+ // Row value filter is used to filter rows for value update
+ df.update { age }.where { name.firstName == "Alice" && name.lastName == "Cooper" }.with { 16 }
+ // SampleEnd
+ .format().perRowCol { row, _ ->
+ val lastName = df[row.index()].name.lastName
+ lastNameToColorUpdateCondition(lastName)?.let { color ->
+ background(color) and textColor(black)
+ }
+ }
+ .saveDfHtmlSample()
+ }
+
+ @Test
+ fun updateWithCondition_strings() {
+ // SampleStart
+ // Row value filter is used to filter rows for value update
+ df.update("age")
+ .where {
+ "name"["firstName"]() == "Alice" &&
+ "name"["lastName"]() == "Cooper"
+ }
+ .with { 16 }
+ // SampleEnd
+ }
+
+ @Test
+ fun gatherWithCondition_properties() {
+ // SampleStart
+ // Row value filter is used to gather only unfilled profile fields
+ df.gather { age and city and weight and isHappy }
+ .where { it == null }
+ .into("field", "value")
+ // SampleEnd
+ .defaultHeaderFormatting { "field"() and "value"() }
+ .saveDfHtmlSample()
+ }
+
+ @Test
+ fun gatherWithCondition_strings() {
+ // SampleStart
+ // Row value filter is used to gather only unfilled profile fields
+ df.gather("age", "city", "weight", "isHappy")
+ .where { it == null }
+ .into("field", "value")
+ // SampleEnd
+ }
+
+ @Test
+ fun formatWithCondition_properties() {
+ // SampleStart
+ // Row value filter is used to format only rows with minors
+ df
+ .format()
+ .where { age < 18 }
+ .with { background(RgbColor(242, 210, 189)) and textColor(black) }
+ // SampleEnd
+ .saveDfHtmlSample()
+ }
+
+ @Test
+ fun formatWithCondition_strings() {
+ // SampleStart
+ // Row value filter is used to format only rows with minors
+ df
+ .format()
+ .where { "age"() < 18 }
+ .with { background(RgbColor(242, 210, 189)) and textColor(black) }
+ // SampleEnd
+ }
+}