CSV Column Math
Add the column the spreadsheet would have given you: a line total, a margin, a unit price, a share of the total. Write the formula with column names in braces — {price} * {qty} — and every row is computed at once, including the rows where a cell is empty or a divisor is zero, which are reported rather than silently turned into NaN.
CSV Column Math
Every CSV eventually needs a column that is not in it. The usual route is Excel — open,
type a formula in D2, drag it down 40,000 rows, watch the leading zeros vanish
and the dates turn American, then export and hope. This does the one step you wanted and
touches nothing else: same rows, same order, same text in every other column, one new
column at the end.
How to use it
- Paste or drop the CSV. The column names appear under the panes — click one to drop
{that_name}into the formula at the cursor. - Write the formula.
{price} * {qty},({revenue} - {cost}) / {revenue},round({weight} * 2.20462, 1). - Name the new column and choose where it goes — last, first, or straight after an existing column. Use the name of a column that already exists and it is replaced in place.
- Read the status line. It says how many rows computed, and how many came out blank because a cell was empty, a cell was not a number, or a divisor was zero.
The formula language
Column names go in braces: {unit price} works with the space in it, which is why
braces rather than bare words. Everything else is what you would type into a spreadsheet.
- Arithmetic —
+ - * / %,^for powers, and brackets. Precedence is the usual one, so1 + 2 * 3is 7 and2 ^ 3 ^ 2is 512. - Comparisons —
> < >= <= =and<>, plusand,or,not. They produce 1 or 0, which is often the column you actually wanted. - Rounding —
round(x),round(x, 2),floor,ceil,trunc. Halves round away from zero, the way an invoice does — not JavaScript's default, which rounds −2.5 to −2 and loses a cent on every refund. - Maths —
abs,sqrt,pow(a,b),mod(a,b),sign,exp,ln,log(x)orlog(x, base), and the constantspiande. - Across the row —
min,max,sum,avg,counttake as many arguments as you like:max({q1}, {q2}, {q3}). - Conditionals —
if(test, then, else), and it short-circuits, soif({qty} > 0, {total} / {qty}, 0)never divides by zero.isblank({col})andisnum({col})test a cell. - Down the column —
total({col}),mean({col}),colmin({col}),colmax({col}),colcount({col})read the whole column in a first pass, so{amount} / total({amount})gives each row's share.cumsum({amount})is the running total in row order. - Row number —
row()is 1 for the first data row.
Formulas are parsed, not evaluated. There is no eval anywhere in
this page: the text becomes a small tree of operations and nothing else. A formula pasted from
a colleague cannot run code in your browser.
Numbers as they really appear in CSVs
Exported data is rarely a clean 1234.5. With read messy numbers
on — the default — these all become numbers:
$1,234.50and€1,234.50— currency symbols and thousands separators are dropped.1.234,50— European format. The decimal mark is decided by which separator comes last, so both conventions work in the same file.12%— becomes 0.12, because that is what it means in arithmetic.(45)— accounting notation for −45.
Turn it off and only a plain number counts, which is the right setting when a column that should be numeric secretly is not and you want to know rather than get an answer.
What happens to the rows that cannot be computed
A spreadsheet writes #DIV/0! or #VALUE! into the cell and moves on,
and those strings then travel through your pipeline as data. Here the cell is left
empty and the reason is counted in the status line:
“1,204 of 1,210 rows computed into "total" · 4 left blank — an input cell was empty · 2
left blank — division by zero.” If you would rather have a number, switch the empty-cell
or non-numeric handling to treat as 0 — but do it on purpose, having seen the count.
Examples
{price} * {qty}— Line total.round({price} * {qty} * 1.2, 2)— Line total with 20% VAT, to the cent.({revenue} - {cost}) / {revenue}— Margin as a fraction — tick as a percentage for38.4%.{amount} / total({amount})— Each row's share of the file's total.cumsum({amount})— Running balance down the file.if({stock} < {reorder_at}, 1, 0)— A reorder flag you can filter on.if({qty} > 0, {total} / {qty}, 0)— Unit price, without a division by zero.round(({temp_f} - 32) * 5 / 9, 1)— Fahrenheit to Celsius.max({q1}, {q2}, {q3}, {q4})— Best quarter.{price} * (1 - {discount}) - {cost}— Profit after a discount held as 0.15.
Limits
- Numbers only. The result is a number, not text — to build a string from other columns use combine columns or the template mode of add a column.
- No dates. Date arithmetic needs a date parser and a timezone policy; date formats owns that job.
- No cross-row references. Other than the column aggregates and
cumsum, a formula sees one row at a time. For group totals use group by, and for a full query language SQL over CSV. - Floating point is floating point. Results are written to 12 significant digits so that
0.1 + 0.2comes out as0.3; for money, set the decimals or useround(x, 2).
Privacy
100% client-side. The file is parsed and computed in your browser; nothing is uploaded. See the privacy policy.
Related
Add a column for constants, row numbers and templates · Clean numbers to fix the source column instead · Group by for subtotals · SQL over CSV when one formula is not enough · Filter rows to keep the ones your new column flags · Stats for the column you just built.