Data Storytelling
In Lesson 1 you built a report that updates itself. It is correct, reproducible, and ignored. Priya ships hers every Monday to Dev, the regional manager. Dev opens twenty reports that morning and gives each about thirty seconds. He skims Priya's first paragraph, which describes how the data was pulled, glances at a table, and moves on. He never reaches the finding at the bottom, the one that needed a decision this week.
A correct report that nobody acts on has failed. This lesson is the other half of the job: structuring what you found so a busy reader gets it, and acts on it, in thirty seconds.
By the end of this lesson you will be able to:
- Explain why a report must lead with the answer instead of building up to it
- Structure a data story as the inverted pyramid: Answer, then Evidence, then Detail
- Write a one-paragraph executive summary: the finding, the number, and the recommended action
- Pick and title the single chart that carries your headline
Prerequisites: you can run R and load a package with library(), you have built a basic ggplot (data, then aes(), then a geom) in The Grammar of Graphics, you know the dplyr verbs from The dplyr Verbs, and you have a reproducible report from Lesson 1. Every new term is defined as it appears.
The widget below is the report we are building toward. Toggle between Source (.qmd) and Rendered, and notice it opens with the answer, not the setup.
Your reader is busier than you think
Here is the trap. You spent hours on the analysis, so you write it up the way you lived it: where the data came from, how you cleaned it, what you explored, and finally, at the end, what you found. That order is honest. It is also exactly backwards for the person reading it.
Dev does not want the journey, he wants the destination, fast, because he has nineteen more reports and a 9 a.m. meeting. If your single most important finding sits in the last paragraph, you are betting a whole week of work on him reading to the end. He will not.
So the question for the rest of this lesson is simple: what is the one thing Dev must know, and how do we get it in front of him in the first ten seconds?
Lead with the answer
The fix has a name borrowed from briefing rooms: BLUF, Bottom Line Up Front. State your conclusion and your recommendation in the very first sentence, before any setup. A report written this way reads as the analysis reversed: you worked bottom-up from data to a finding, but you present top-down from the finding back to the data.
Watch what that does to Priya's opening sentence:
| Opening | What Dev takes away in five seconds |
|---|---|
| Buried: "We pulled six stores of weekly sales and joined last week to compare trends across the chain..." | Nothing he can act on yet. He is still reading about your method. |
| Answer-first: "Revenue is down 10% over three weeks, and almost all of it is two stores. Recommend a check at Riverside and Lakeside this week." | The finding AND the action. He could forward this one sentence and be right. |
Same facts, same data, same honesty. The only thing that changed is what comes first.
Which opening leads with the answer?
Priya has three candidate first sentences for her weekly report. Dev will read exactly one of them before deciding whether to keep going. Which one leads with the answer?
The inverted pyramid
If the answer goes first, what goes next? Journalists solved this a century ago with the inverted pyramid: start with the single most important point, then add supporting detail in falling order of importance, so a reader can stop at any moment and still have the gist. A data story has three layers, in exactly that order.
A reader who stops after the Answer still leaves knowing what to do. A reader who wants proof reads the Evidence. Only the rare reader who wants to audit your work reaches the Detail, and that is fine: you wrote it for them, but you did not make everyone else wade through it first.
Write the executive summary
The Answer layer is one short paragraph called the executive summary, and a good one has exactly three ingredients:
- The finding in plain language: revenue is sliding, and it is concentrated.
- The number that sizes it: down about 10% over three weeks.
- The recommended action: check Riverside and Lakeside this week.
A finding with no number is vague; a number with no recommendation is trivia. You need all three. Here is Priya's, in two sentences:
Chain revenue has fallen for three straight weeks, down about 10% to $31k, and almost the entire drop comes from two stores. Recommend a focused price and promotion review at Riverside and Lakeside before the next refresh.
Where does "two stores" come from? From the data, not a hunch. Each lesson runs in a fresh R session, so we build this week's per-store numbers right here, then sort by the week-over-week change so the worst stores rise to the top:
The two stores at the top of that sorted table are the whole story. That is what turns a vague "look into declining sales" into a specific, do-it-this-week recommendation.
One chart carries the headline
The Evidence layer needs one chart, and it has one job: make the finding obvious at a glance. That takes two decisions. First, plot the thing that shows the finding, here the trend over time, not just this week's totals. Second, choose the encoding that makes the pattern jump out. The same six weeks of chain revenue can be drawn three ways:
Switch between the geoms. Points scatter the eye, bars are readable but heavy, and the line connects them into the one thing Dev needs to see: a slope heading down. Same numbers, but the line tells the story.
Now the same chart in R. We build the six-week series inline, draw it, and, crucially, put the finding in the title, not "Revenue by week" but what the revenue is actually doing:
Compute the headline number
Your executive summary says revenue is "down about 10%." That number should be computed, not eyeballed, so it stays right when next week is added (exactly the inline-code idea from Lesson 1). Using the weekly data you just built, fill in the blank to compute the percent drop from the peak week to the latest week.
Show answer
peak <- max(weekly$revenue)
latest <- weekly$revenue[nrow(weekly)]
pct_drop <- round((peak - latest) / peak * 100)
pct_drop
#> [1] 10What does this report need?
A colleague sends you a draft. It opens with two paragraphs on data sources and cleaning, then a full 40-row table of every store and week, and the actual finding ("two stores are dragging the chain down") is the last sentence on page two. The numbers are all correct. What is the single most important fix?
References
A few authoritative places to take this further:
- Cole Nussbaumer Knaflic, Storytelling with Data - the standard practical guide to turning a chart into a message a reader acts on.
- Nielsen Norman Group: The Inverted Pyramid - why leading with the conclusion beats building up to it, with the usability research behind it.
- ggplot2: Elegant Graphics for Data Analysis (Wickham) - the canonical reference for titling, labelling and annotating the chart that carries your headline.
- R for Data Science (2e) - Wickham, Cetinkaya-Rundel and Grolemund on the communication half of the analysis workflow.
Lesson 2 complete
A correct report is only half the job, and this lesson was the other half. You learned to lead with the answer (BLUF: the finding and the recommended action first), to shape the write-up as an inverted pyramid, Answer then Evidence then Detail, and to open with a one-paragraph executive summary carrying the finding, the number, and the action. You saw that one chart carries the headline when you plot the finding and title it with what to see, and you made the headline number reproducible in R so it never goes stale.
Next, Lesson 3: AI-assisted analysis in R. You will use a large language model to summarize and label data straight from R, and get a clear-eyed guide to when an LLM is worth trusting in an analysis, and when it is not.