is there a way to sum column values in a standard table?

Yes, there are just two things to make sure:

- you need to store the data somewhere
*before*creating the table - you need to make sure that you operate on numbers and not
`content`

For demonstration, letâs look at a table you may be starting with:

```
#table(
columns: 2,
align: right,
stroke: none,
table.header([Col A], [Col B]),
table.hline(),
[1], [2],
[3], [4],
[5], [6],
table.hline(),
[9],
[12],
)
```

This table has three rows of actual data, a header, and manually calculated column sums.

Advice 1 means you should create a variable to store the data before putting it into the table:

```
#let data = (
([1], [2]),
([3], [4]),
([5], [6]),
)
#table(
// ...
table.hline(),
..data.flatten(),
table.hline(),
// ...
)
```

`data`

contains an array of arrays â each element is a row, and each row consists of the two columns. This is easier for us to work with, but we need `flatten()`

because `table()`

doesnât accept this kind of nested array.

Advice 2 means that instead of writing `[1]`

, we should just use `1`

, so that we can actually calculate something:

```
#let data = (
(1, 2),
(3, 4),
(5, 6),
)
#table(
// ...
table.hline(),
..data.flatten().map(num => [#num]),
table.hline(),
// ...
)
```

Again, `table()`

canât simply show numbers, thus I also used `map(num => [#num])`

to convert each number back into content before displaying.

But by doing this, weâre now ready to actually do calculations with the numbers:

```
// ...
#let col-a-sum = data.map(row => row.at(0)).sum()
#let col-b-sum = data.map(row => row.at(1)).sum()
#table(
// ...
table.hline(),
..data.flatten().map(num => [#num]),
table.hline(),
[#col-a-sum], [#col-b-sum],
)
```

This extracts from each row the first or second column, respectively, and sums them up. Then, the numbers are added to the table as content.

In this example, all columns were summed up. To avoid duplication, you could do all columns in a loop like this:

```
#let col-sums = ()
#for i in array.range(data.first().len()) {
let col-sum = data.map(row => row.at(i)).sum()
col-sums.push(col-sum)
}
#table(
// ...
..col-sums.map(num => [#num]),
)
```

This can be shortened in a few ways; I wanted to show a loop as the main solution because itâs not as terse as these other options, but they do exist:

## Shorter sums for all columns

```
// like the loop before, but using `map()`
// instead of pushing element by element
#let col-sums = array.range(data.first().len()).map(i => {
data.map(row => row.at(i)).sum()
})
// using a sort of transpose operation to get
// an array of columns from the array of rows
#let col-sums = array.zip(..data).map(array.sum)
```

As a final example, hereâs how to sum up all columns read from a csv file with header:

## Table with column sums from CSV

```
#let csv-data = csv.decode(```
Col A,Col B
1,2
3,4
5,6
```.text)
// When the data come from a file, you'd write this instead:
// #let csv-data = csv("filename.csv")
#let (header, ..data) = csv-data
#let col-sums = array.zip(..data).map(column => column.map(int).sum())
#table(
columns: 2,
align: right,
stroke: none,
table.header(..header),
table.hline(),
..data.flatten(),
table.hline(),
..col-sums.map(num => [#num]),
)
```

Whatâs a bit different here is that instead of having to convert the data to `content`

, it comes out of the csv file as strings. So we donât need to convert to content (strings work in tables), but *do* need to convert each number to `int`

before calculating.

Please see tabut package. From " Aggregation using Map and Sum" of their docs:

```
#import "usd.typ": usd
#import "example-data/titanic.typ": titanic, classes
#table(
columns: (auto, auto),
[*Fare, Total:*], [#usd(titanic.map(r => r.Fare).sum())],
[*Fare, Avg:*], [#usd(titanic.map(r => r.Fare).sum() / titanic.len())],
stroke: none
)
```

Thanks a lot.

I will try to adapt to my tables

OK I will look. Thank a lots

Given the following code reading data from a csv-File:

```
#let csv-data = csv.decode(```
Text, Value
"A",2
"B",4.5
"C",6
```.text)
#let (header, ..data) = csv-data
This I have copied from another example.
```

How can I get the the sum of the variable âValueâ. I tried all kind of variations, breaking down much more complex operations, but to no avail.

and re csv:

Is there a problem with doing it this way?

Thank you for the fast answer.

Regrettably #col-b-sum returns 24.56 which is a string concatenation of the values.

I had this result before in one of my myriad attempts.

Thatâs what the

part is about. If you look at the CSV snippet, it has a `column.map(int)`

in there, to convert the strings into integers. Admittedly, itâs easy to miss when you donât look what youâre looking for. The complete adapted code (but converting to float, not int) would be this:

```
#let col-b-sum = data.map(row => float(row.at(1))).sum()
```

I solved it myself

```
#let csv-data = csv.decode(```
Text, Value
"A",2
"B",4.5
"C",6
```.text)
#let (header, ..data) = csv-data
#let numeric_data = data.map(row => float(row.at(1))) // convert to float
#let Value_Sum = numeric_data.sum()
#Value_Sum
```

Sorry, had not seen your answer early enough, more elegant than âmyâ solution.

Thanks a lot for your assistance.