# Summary statistics

> For the complete documentation index, see [llms.txt](https://kotlin.github.io/dataframe/llms.txt).

Basic summary statistics:

* [count](count.html)

* [valueCounts](valuecounts.html)

API reference: [api package](https://kotlin.github.io/dataframe/api-docs/core/org.jetbrains.kotlinx.dataframe.api/index.html)

Aggregating summary statistics:

* [sum](sum.html)

* [min/max](minmax.html)

* [mean](mean.html)

* [std](std.html)

* [median](median.html)

* [percentile](percentile.html)

Every summary statistic can be used in aggregations of:

* [DataFrame](dataframe.html)

* [DataColumn](datacolumn.html)

* [GroupBy DataFrame](#groupby-statistics)

* [Pivot](#pivot-statistics)

* [PivotGroupBy](pivot.html#pivot-groupby)

```KOTLIN
df.mean()
df.age.sum()
df.groupBy { city }.mean()
df.pivot { city }.median()
df.pivot { city }.groupBy { name.lastName }.std()
```

[sum](sum.html), [mean](mean.html), [std](std.html) are available for (primitive) number columns of types `Int`, `Double`, `Float`, `Long`, `Byte`, `Short`, and any mix of those.

[min/max](minmax.html), [median](median.html), and [percentile](percentile.html) are available for self-comparable columns (so columns of type `T : Comparable<T>`, whose values are mutually comparable, like `DateTime`, `String`, etc.) which includes all primitive number columns, but no mix of different number types.

In all cases, `null` values are ignored.

`NaN` values can optionally be ignored by setting the `skipNaN` flag to `true`. When it's set to `false`, a `NaN` in the input will be propagated to the result.

Big numbers (`BigInteger`, `BigDecimal`) are not supported by [sum](sum.html), [mean](mean.html), [std](std.html), and [cumSum](cumsum.html) — these operations throw at runtime for such columns. [min/max](minmax.html) work with them, as they only compare values; [median](median.html) and [percentile](percentile.html) are not explicitly supported and work only for some overloads. Please [convert](convert.html) big numbers to primitive types before using statistics, or compute the statistic manually with Java big number arithmetic.

When statistics `x` is applied to several columns, it can be computed in several modes:

* `x(): DataRow` computes separate value per every suitable column

* `x { columns }: Value` computes single value across all given columns

* `xFor { columns }: DataRow` computes separate value per every given column

* `xOf { rowExpression }: Value` computes single value across results of [row expression](datarow.html#row-expressions) evaluated for every row

(See [column selectors](columnselectors.html) for how to select the columns for these operations)

[min/max](minmax.html), [median](median.html), and [percentile](percentile.html) have additional mode `by`:

* `minBy { rowExpression }: DataRow` finds a row with the minimal result of the [rowExpression](datarow.html#row-expressions)

* `medianBy { rowExpression }: DataRow` finds a row where the median lies based on the results of the [rowExpression](datarow.html#row-expressions)

To perform statistics for a single row, see [row statistics](rowstats.html).

```KOTLIN
df.sum() // sum of values per every numeric column
df.sum { age and weight } // sum of all values in `age` and `weight`
df.sumFor(skipNaN = true) { age and weight } // sum of values per `age` and `weight` separately
df.sumOf { (weight ?: 0) / age } // sum of expression evaluated for every row
```

## groupBy statistics

When a statistic is applied to a [GroupBy DataFrame](groupby.html#transformation), it is computed for every data group.

If a statistic is applied in a mode that returns a single value for every data group, it will be stored in a single column named according to the statistic name.

```KOTLIN
df.groupBy { city }.mean { age } // [`city`, `mean`]
df.groupBy { city }.meanOf { age / 2 } // [`city`, `mean`]
```

[Embedded content](resources/org.jetbrains.kotlinx.dataframe.samples.api.Analyze.statisticGroupBySingle.html)

You can also pass a custom name for the aggregated column:

```KOTLIN
df.groupBy { city }.mean("mean age") { age } // [`city`, `mean age`]
df.groupBy { city }.meanOf("custom") { age / 2 } // [`city`, `custom`]
```

[Embedded content](resources/org.jetbrains.kotlinx.dataframe.samples.api.Analyze.statisticGroupBySingleNamed.html)

If a statistic is applied in a mode that returns a separate value for every column in a data group, aggregated values will be stored in columns with the original column names.

```KOTLIN
df.groupBy { city }.meanFor { age and weight } // [`city`, `age`, `weight`]
df.groupBy { city }.mean() // [`city`, `age`, `weight`, ...]
```

[Embedded content](resources/org.jetbrains.kotlinx.dataframe.samples.api.Analyze.statisticGroupByMany.html)

## pivot statistics

When a statistic is applied to `Pivot` or `PivotGroupBy`, it is computed for every data group.

If a statistic is applied in a mode that returns a single value for every data group, it will be stored in a `DataFrame` cell without any name.

Properties:

```KOTLIN
df.groupBy { city }.pivot { name.lastName }.mean { age }
df.groupBy { city }.pivot { name.lastName }.meanOf { age / 2.0 }
```

Strings:

```KOTLIN
df.groupBy("city").pivot { "name"["lastName"] }.mean("age")
df.groupBy("city").pivot { "name"["lastName"] }.meanOf { "age"<Int>() / 2.0 }
```

[Embedded content](resources/org.jetbrains.kotlinx.dataframe.samples.api.Analyze.statisticPivotSingle.html)

If a statistic is applied in such a way that it returns separate value per every column in a data group, every cell in the nested dataframe will contain [DataRow](datarow.html) with values for every aggregated column.

```KOTLIN
df.groupBy { city }.pivot { name.lastName }.meanFor { age and weight }
df.groupBy { city }.pivot { name.lastName }.mean()
```

[Embedded content](resources/org.jetbrains.kotlinx.dataframe.samples.api.Analyze.statisticPivotMany.html)

To group columns in aggregation results not by pivoted values, but by aggregated columns, apply the `separate` flag:

```KOTLIN
df.groupBy { city }.pivot { name.lastName }.meanFor(separate = true) { age and weight }
df.groupBy { city }.pivot { name.lastName }.mean(separate = true)
```

[Embedded content](resources/org.jetbrains.kotlinx.dataframe.samples.api.Analyze.statisticPivotManySeparate.html)

