Shape / columns · All operations

Aggregate across columns in each row

A variant of Add a calculated column

Combine the values of several columns within each row, such as their sum, mean or maximum, into a new column.

Status

In arcform

Runs as a SQL step

arcform carries it as a sql: step today.

The DuckDB step

Sum, mean and maximum across the columns of each row

SQL
CREATE TEMP TABLE scores AS SELECT * FROM (VALUES
  (1, 10, 20, 30),
  (2,  5, NULL, 15),
  (3, NULL, NULL, NULL)
) t(id, q1, q2, q3);
CREATE TEMP TABLE result AS
SELECT id, list_sum([q1, q2, q3]) AS total, list_avg([q1, q2, q3]) AS mean, list_max([q1, q2, q3]) AS best FROM scores;
SELECT * FROM result ORDER BY id;
SELECT CASE WHEN ((SELECT map_from_entries(list((id, [total, mean, best]::DOUBLE[]) ORDER BY id)) FROM result WHERE id < 3) = MAP {1: [60.0, 20.0, 30.0], 2: [20.0, 10.0, 15.0]} AND (SELECT count(total) + count(mean) + count(best) FROM result WHERE id = 3) = 0) THEN 'as expected' ELSE error('the row sums, means and maxima were not 60, 20 and 30 then 20, 10 and 15 with nulls skipped') END AS verdict;
  • The statement builds its own data.
  • It needs nothing installed beyond DuckDB itself.
  • The statement checks its own result and raises an error when it is wrong: “the row sums, means and maxima were not 60, 20 and 30 then 20, 10 and 15 with nulls skipped”.
  • It passed on DuckDB v2.0.0 (Cyanoptera) d54cbbe3df.

What other tools call it

Meridian's classification; an independent blind rating agreed on 95.7% of 324 rows (variant, version 3).

KNIME Analytics Platform (1)
  • Column Aggregatorread 2026-09-27

    Aggregate the values of several columns within each row into a new column

Polars (3)
  • DataFrame.foldread 2026-09-27

    Reduce across the columns row by row with a user function that combines two Series

  • foldread 2026-09-27

    Left fold across columns row by row with a user function and a start value

  • reduceread 2026-09-27

    Left fold across columns row by row with a user function, no start value

RapidMiner Studio (2)

Background

Aggregating across columns combines the values of several columns within each row, such as their sum, mean or maximum, into a new column.[1][2]

When to use it

In dplyr, mean(c(x, y, z)) inside mutate() computes the mean across all rows on a regular data frame, and the mean for each row on a row-wise data frame.[2]

Polars' sum_horizontal ignores null values by default, and with ignore_nulls set to False any null input leads to a null output.[3] Decide what a row whose values are all missing should get, a missing total or zero, and check which one the engine gives rather than assuming. (Meridian's view)

PostgreSQL's GREATEST and LEAST ignore NULL values in their arguments and return NULL only if every argument is NULL.[4] PostgreSQL's NULL handling in GREATEST and LEAST deviates from the Structured Query Language (SQL) standard, under which the result is NULL if any argument is NULL, as some other databases do.[4]

The method

DuckDB's list_aggregate runs a named aggregate function on a list's elements, so list_aggregate([1, 2, NULL], 'min') returns 1.[5] Wrapping a DuckDB COLUMNS expression in UNPACK expands its columns into the surrounding function, so coalesce(UNPACK(COLUMNS(['a', 'b', 'c']))) gives a single column.[6]

The rowSums() and rowMeans() functions take a multi-row data frame as input, so sums and means across columns need no row-wise data frame.[2]

Compared with the alternatives

RapidMiner's Generate Aggregation operator can be considered a blend of its Generate Attributes and Aggregate operators.[1] DuckDB's UNPIVOT statement turns wide tables into long tables.[7] Aggregate across columns when the columns are a fixed set of measurements of one thing, such as q1 to q4; when they are one variable spread wide, unpivoting and aggregating down the rows is often the cleaner shape. (Meridian's view)