How to transpose a/b test results csv for reporting
- Step 1Export results from your experimentation platform — Download the results CSV from Optimizely, VWO, Statsig, or your platform. Most export with one variant per row and metrics as columns — the shape this tool flips into a variant-per-column comparison.
- Step 2Trim stat rows you don't want in the chart — Results files often append confidence-interval, p-value, or segment-breakdown rows. Because the flip transposes every row, those become columns in the output. Drop the ones you don't want first with csv-row-limiter or csv-cleaner.
- Step 3Drop the file onto the tool — The transpose runs automatically on load — there are no options, no metric picker, and no orientation toggle. The delimiter is auto-detected and the flip always swaps rows and columns.
- Step 4Confirm the swap from the stat cards — Check
Rows before/Columns beforeagainstRows after/Columns after. A 3-variant results table with 6 metric columns (header + 3 variants) shows4 → 6rows and6 → 4columns. If the numbers already matched your target layout, the file didn't need flipping. - Step 5Read the preview — first column is your old header — The preview shows the first 10 output rows. The first column holds your original metric labels; each variant becomes a column. There's no traditional header row afterward — every output row is one metric, labelled by its first cell.
- Step 6Download and drop into your report — Output downloads as
<name>.transposed.csv(plain UTF-8, no BOM). Paste into Google Sheets, Excel, or your BI tool for the side-by-side chart. If percent symbols or accented metric names look off in Excel, re-save asCSV UTF-8or pre-clean with csv-cleaner.
Before and after: a 3-variant results transpose
A variant-per-row export (left) and the variant-per-column comparison (right). The flip is one-for-one — nothing is recomputed.
| Aspect | Source (variant-per-row) | Output (variant-per-column) |
|---|---|---|
| Grid shape | 4 rows × 6 columns (header + 3 variants) | 6 rows × 4 columns |
| First column after flip | Header Variant, Visitors, Conversions, CR, Uplift, p | Becomes the metric-label column |
| A variant label | Row begins Treatment A, ... | Treatment A becomes a column header |
| A conversion rate | 4.21% in the CR column | 4.21% preserved as text in the CR row |
| A p-value | 0.032 | Carried across verbatim — never re-tested |
What the transposer does and does not do for experiments
It's an orientation tool, not a stats tool. Keep these straight before reporting.
| Capability | Supported? | Detail |
|---|---|---|
| Swap variants ↔ metrics orientation | Yes | Pure flip: cell [r][c] → [c][r] |
| Recompute CR / uplift / lift | No | Text-only; 4.21% and +12% are carried across, never recalculated |
| Re-run significance / p-value | No | p-values and CIs are moved as text; use your platform or a stats tool |
| Combine duplicate variant rows | No | No aggregation; duplicates become duplicate columns |
| Pick which row becomes header | No | Zero options; old header always moves to column 1 |
| Pad ragged rows | Yes | Short rows (e.g. Control with no uplift cell) padded to widest row |
Free vs Pro limits for results files
CSV Transposer is a Pro tool. Experiment summary files are usually small.
| Limit | Free | Pro |
|---|---|---|
| Max file size | 2 MB | 100 MB |
| Max rows processed | 500 | 100,000 |
| Practical note | A summary table is a handful of rows — easily under the cap | Raw per-user event logs are the wrong input; summarise first |
Cookbook
Real experiment-results shapes and how the raw flip handles each. Metrics illustrative.
Variants as rows → variants as columns
ExampleThe core case. A results summary with one variant per row becomes a side-by-side comparison where Control and each treatment sit in adjacent columns under every metric.
Input (variant-per-row): Variant,Visitors,Conversions,CR Control,10000,400,4.00% Treatment A,10050,442,4.40% Treatment B,9980,418,4.19% Download (.transposed.csv): Variant,Control,Treatment A,Treatment B Visitors,10000,10050,9980 Conversions,400,442,418 CR,4.00%,4.40%,4.19%
p-values and uplift are carried, never recomputed
ExampleAfter flipping, the comparison shows each variant's stats side by side — but every value is exactly what your platform exported. The transposer does no math.
Input: Variant,CR,Uplift,p-value Control,4.00%,—,— Treatment A,4.40%,+10.0%,0.032 Output (Control's blank stat cells preserved): Variant,Control,Treatment A CR,4.00%,4.40% Uplift,—,+10.0% p-value,—,0.032
Control row shorter than treatment rows gets padded
ExampleControl often has no uplift or p-value cell. The transposer pads short rows to the widest row, so the comparison table stays rectangular with blanks where Control had no stat.
Input (Control row has 2 cells, others have 4): Variant,CR,Uplift,p-value Control,4.00% Treatment A,4.40%,+10.0%,0.032 Output (Control padded to 4 cells): Variant,Control,Treatment A CR,4.00%,4.40% Uplift,,+10.0% p-value,,0.032
Segment-breakdown rows become columns (often unwanted)
ExampleIf your export appends per-segment rows (mobile, desktop), transposing turns each into a column. Usually you want a clean variant comparison, so trim segment rows first.
Input (extra segment rows): Variant,CR Control,4.00% Treatment A,4.40% Mobile-Control,3.80% Mobile-Treatment,4.10% Transpose spreads all four as columns: Variant,Control,Treatment A,Mobile-Control,Mobile-Treatment CR,4.00%,4.40%,3.80%,4.10% Trim segment rows with csv-row-limiter first for a clean two-variant chart.
Tab-separated export from a data-warehouse query
ExampleExperiment results pulled via SQL are often tab-separated. The delimiter is auto-detected, so a TSV flips without any setting.
Input (tab-separated, shown with → as tab): Variant→Visitors→CR Control→10000→4.00% Treatment→10050→4.40% Output (tab delimiter detected and preserved): Variant→Control→Treatment Visitors→10000→10050 CR→4.00%→4.40%
Errors and edge cases
Real errors and silent failures sourced from each platform's own documentation. Match the wording to the row, fix what the row says to fix.
Conversion rate / uplift not recomputed
Not recalculatedThe transposer is text-only — 4.40% and +10.0% are carried across exactly as exported, never recalculated from visitors and conversions. If your source values were wrong, the flip preserves the error. Recompute in your platform or a spreadsheet; the transposer only changes orientation.
p-value / significance not re-tested
Not recalculatedp-values and confidence intervals are moved as plain text. The transposer does not re-run any statistical test or recompute significance. Treat the flipped table as a presentation of the platform's numbers, not a re-analysis. For a fresh test, use your experimentation platform or a stats package.
Duplicate variant rows not combined
Not aggregatedIf a variant appears on more than one row (e.g. daily snapshots stacked together), the flip produces a column per row — it never sums or averages. Aggregate with a PivotTable or deduplicate with csv-deduplicator before transposing if you need one column per variant.
Segment-breakdown rows become extra columns
By designPer-segment rows (mobile/desktop, geo) transpose into extra columns, cluttering a simple variant comparison. The tool can't tell a segment row from a variant row. Trim the rows you don't want with csv-row-limiter or csv-cleaner before flipping.
Ragged Control row
PaddedControl frequently has no uplift or p-value cell, making its row shorter than treatment rows. The transposer pads short rows to the widest row with empty strings, so the output comparison table is rectangular with blanks where Control had no stat — expected, not an error.
Raw per-user event log fed in by mistake
Wrong inputA raw events log (one row per user/exposure) transposes into a file with one column per user — useless for reporting and likely to blow the row/column limits. Summarise to a per-variant table first (a PivotTable or GROUP BY), then transpose the summary. The transposer never aggregates.
Unquoted comma inside a metric label
Parse riskA metric name like Revenue, per user written without quotes in a comma-delimited file is read as two cells and shifts the row. That's a source defect; the flip carries the misalignment across. Quote such labels at the source or fix with csv-find-replace first.
Free-tier cap exceeded
BlockedFree processing stops at 2 MB and 500 rows; this is a Pro tool. A summary results table is tiny, so the cap usually only bites if you accidentally fed a raw event log. Summarise first, or upgrade to Pro (100 MB / 100,000 rows).
Source already variant-per-column
ExpectedIf your file already has variants across the columns and metrics down the rows, transposing flips it back to variant-per-row. The stat cards make the swap obvious. Transpose twice and you're back to the start; check orientation before downloading.
Percent and currency symbols not normalised
Preserved4.40%, $1,240, +12.0%, and — for blanks are all carried across as text — the transposer never strips symbols or converts to decimals. If your chart needs raw numbers, normalise with csv-find-replace before transposing.
Frequently asked questions
Does the transposer recalculate conversion rates or uplift?
No. It is text-only and changes orientation only — 4.40%, +10.0%, and every other value are carried across exactly as your platform exported them. It never recomputes a rate from visitors and conversions, and it never recalculates lift. If a source value was wrong, the flip preserves it; fix the math in your platform or a spreadsheet.
Will it re-run the significance test or p-value?
No. p-values and confidence intervals are moved as plain text, not re-tested. The transposed table is a re-orientation of your platform's numbers for presentation — not a fresh statistical analysis. Use your experimentation tool or a stats package if you need to recompute significance.
Can I feed it my raw per-user event log?
You can, but you shouldn't — it transposes into one column per user, which is useless for reporting and may exceed the row/column limits. Summarise to a per-variant results table first (a PivotTable or a GROUP BY query), then transpose that summary into a side-by-side comparison.
My Control row is shorter than the treatment rows — is that a problem?
No. Control often lacks uplift and p-value cells. The transposer pads every short row to the width of the widest row with empty strings, so the output comparison table stays rectangular with blank cells where Control had no stat. That's the expected result.
How do I stop segment rows from cluttering the comparison?
Trim them before flipping. Per-segment rows (mobile/desktop, geo) transpose into extra columns because the tool can't distinguish them from variant rows. Drop the unwanted rows with csv-row-limiter or csv-cleaner, then transpose for a clean variant-only chart.
Does it combine duplicate variant rows?
No — there's no aggregation. If a variant appears more than once (e.g. stacked daily snapshots), you get a column per row. Deduplicate with csv-deduplicator or aggregate with a PivotTable first if you need one column per variant.
Can I choose which row becomes the headers after flipping?
No — the transposer has zero options. The original header row always becomes the first column, and the flip runs automatically on drop. Promoting a specific row/column to headers is a pivot operation; do that in Excel or pandas.
What delimiter does it expect from my export?
Whatever your file uses — comma, semicolon, or tab are all auto-detected. SQL-pulled results are often tab-separated and flip without any setting; European exports using semicolons work too, with decimal commas left untouched inside values.
Are percent and currency symbols preserved?
Yes, exactly. 4.40%, $1,240, +12.0%, and — placeholders are all carried across as text — nothing is stripped or converted to a decimal. If your chart needs raw numbers, normalise with csv-find-replace before transposing.
Is my experiment data uploaded anywhere?
No. Parsing and transposing run entirely in your browser via PapaParse. Experiment names, internal metrics, and any revenue figures never reach a server. If signed in, only an anonymous run counter (no content) is recorded for your dashboard.
How large a results file can I transpose?
Free tier caps at 2 MB and 500 rows; this is a Pro tool, with Pro limits of 100 MB and 100,000 rows. A summary results table is tiny, so size is rarely an issue — if you're near the cap, you're probably feeding a raw event log that should be summarised first.
What's the cleanest workflow for a stakeholder comparison chart?
Start from your platform's per-variant summary CSV. Trim segment and stat rows you don't want with csv-row-limiter, drop duplicates with csv-deduplicator if needed, then transpose to get variants as columns. Paste the .transposed.csv into Google Sheets and build the side-by-side chart.
Privacy first
Processing runs locally in your browser with PapaParse. No file is uploaded — only metadata counters are saved for signed-in dashboard stats.