Count what is missing in five categories that add up to the grid, with the tokens that mean missing your choice
Initializing in your browser…
Classify every column against a decider rather than a regex: calendar-checked dates, RFC 4291 addresses, and leading zeros kept out of integer columns
Validate columns against rules that name their definition: the email rule browsers enforce, a URL scheme allowlist, calendar-checked dates, and every failure explained
View, sort and edit a CSV, with an undo stack that goes back exactly one step and a parse report that tells a broken quote from a ragged row
A members export where one row is short a field, one cell holds a space, one holds NULL, and the region column uses NA for North America. Four different facts that a single "missing" bucket turns into one number.
members.csv, 3 columns
id,region,score 1,NA,88 2,NULL, 3,EU 4, ,75
The five categories, which add up to the grid
Present 8 Empty 1 the score in row 2 Whitespace 1 the region in row 4 holds a space Missing marker 1 the region in row 2 holds NULL No cell at all 1 row 3 has no third field Checked: those five add up to 12, which is 4 rows times 3 columns. NA is not in that count: it is North America here, and the marker set says so.
The interesting one is the last row of the count. A scan that walks the fields each row actually has never visits the third field of row 3, so it reports one fewer missing cell while still dividing by the full twelve. The percentage is then wrong and nothing says so. Here the grid is the widest row times the row count and the five categories are checked against it on screen.
Find and count what is missing from a CSV, with every count defined and the counts adding up. Every cell of the grid is exactly one of five things: a value, empty, whitespace only, one of the tokens you name as meaning missing, or no cell at all because the row is short. The five sum to the row count times the column count, and the page checks that and says so.
A missing-data report is nothing but counts and percentages, so the whole job is that each one has a stated denominator and that they partition the grid.
**The five categories are separate because they are different facts.** An empty cell is an absence. A cell holding a space is usually a broken export and is worth knowing about on its own. A cell holding NULL is a statement someone wrote down. And a cell that does not exist, because the row has fewer fields than the widest row, is different again: it is the one a scan that only visits the fields a row actually has never sees, while the total quietly assumes it is there.
**Which tokens mean missing is your decision.** NA is the symbol for sodium, the code for North America and the abbreviation for Namibia, so a tool that decides on your behalf that those are missing data is wrong more often than it is right. The default set is NULL, N/A, NaN, None, nil, #N/A and a lone dash; you can drop it to empty cells only, or widen it to include NA, and the counts change in front of you.
**Per column** you get the five counts, the percentage over a named denominator (the number of data rows), the longest run of consecutive gaps and where it starts, how many of the present cells read as numbers, and the mean, median, minimum and maximum over those. Values are read with a stated decimal grammar rather than parseFloat, so a cell reading 12abc is not the number 12 and does not move the mean.
**Filling a gap invents data,** so nothing is filled unless you ask, and each strategy says what it does. The mean is written with the number of decimals the column already uses, so a column of whole numbers does not gain a .00. A carry-down takes the last present value rather than the cell above, so a run of gaps does not copy a missing value into the next one. Interpolation only fills where there is a present number on both sides. And when two values are equally the most common, nothing is filled and the tie is reported, because picking one silently is a guess dressed as an answer. Whatever a strategy could not fill is counted with the reason.
One number for the whole grid and one per column, each over a denominator you can see, so a 12 percent missing rate means something specific.
Cells holding only whitespace, and rows shorter than the rest, both get their own count instead of being folded into "empty".
Fill by mean, median, most common value, carry forward or back, or interpolate, and see exactly how many cells each strategy filled and how many it could not.
A three column table with one two-field row has nine cells, seven of them values and two that do not exist. A scan that walks only the fields each row has reports nothing missing at all.
With the default marker set, NA is a value: North America is not a missing region. Widen the set and the same file reports those cells as missing.
A column reading 10 and 20 with one gap fills with 15, not 15.00, because the column has no decimal point anywhere in it.
Because it is the symbol for sodium, the country code for Namibia and the region code for North America. Whether it means "not available" in your file is a fact about your data, so it is a choice on the page rather than an assumption in the code.
An empty cell holds nothing. A whitespace cell holds a space or a tab and nothing else, which almost always means something upstream wrote a value it did not have. They are counted apart because they tell you different things.
The grid is as wide as the widest row, and a cell a shorter row does not have is counted in its own category. The report says how many there are. A tool that only visits the fields each row has would report those as nothing at all while still dividing by the full grid.
Because two or more values were equally the most common. There is no single most common value to fill with, so nothing was filled and the page says which values tied.
Often not. Filling invents data, and the invented values then look like measurements. Nothing is filled unless you choose a strategy, and the default for every column is to leave it alone.
Rows and columns are parsed and transformed in memory in your browser. No record ever reaches a server.