cassionData Analysis

Back to the lessonLesson 7 of 8What the report claims

r = 0.039, and everyone expected 0.5

The same deck as the downloads, rendered as a page. Start the slideshow to present it full screen — arrow keys or a click advance one slide, Escape leaves.

Slides · PDFSlides · PowerPoint

  1. Slide 1 / 29

    What this lesson covers

    • The correlation that is not there
    • An interval on a correlation
    • The correlation that is there and says nothing
    • Square it before you describe it
    • Pearson, Spearman, and eleven bad rows
    • Correlated because something else moved both
    • And the clustering from the last lesson
    • Write the sentence
    • Report it whole
    • What comes next
    Speaker notes
    Attendance and endline literacy correlate at 0.039 across 659 students — an interval from −0.04 to +0.12, which is as close to nothing as a dataset gets. The correlation everyone assumes is in the register is not in this one, and reporting that is the finding.
  2. Slide 2 / 29

    The correlation that is not there — In Python (cont.)

    import pandas as pd
    import numpy as np
    
    assessment = pd.read_csv("learning-assessment-2024.v1.csv")
    attendance = pd.read_csv("school-attendance-2024.v1.csv")
    roster = pd.read_csv("school-roster-2024.v1.csv")
    
    MARKS = {"true": True, "Y": True, "false": False, "N": False}
    marked = attendance[attendance["present"].isin(MARKS)].copy()
    marked["attended"] = marked["present"].map(MARKS)
    rate = marked.groupby("student_id")["attended"].mean().rename("attendance")
    
    endline = (assessment[assessment["assessment_round"] == "endline"]
               .pivot_table(index="student_id", columns="domain", values="raw_score"))
    joined = endline.join(rate, how="inner").join(roster.set_index("student_id"))
    
  3. Slide 3 / 29

    The correlation that is not there — In Python (cont.)

    print(joined[["literacy", "numeracy", "attendance"]].corr().round(3))
  4. Slide 4 / 29

    The correlation that is not there — In R

    library(dplyr)
    
    joined |> select(literacy, numeracy, attendance) |> cor(use = "complete.obs")
  5. Slide 5 / 29

    The correlation that is not there

    Pairrn
    Attendance and endline literacy0.039659
    Attendance and endline numeracy−0.006659
    Literacy and numeracy0.849659
  6. Slide 6 / 29

    The correlation that is not there

    • Attendance and literacy correlate at 0.039 — Every education programme document assumes that relationship and most…
    Speaker notes
    Attendance and literacy correlate at 0.039. Every education programme document assumes that relationship and most quote a number for it. In this register it is absent. That is a result, and it needs an interval before it is one.
  7. Slide 7 / 29

    An interval on a correlation — In Python

    def fisher_ci(r, n, z=1.96):
        zr = np.arctanh(r)
        se = 1 / np.sqrt(n - 3)
        return np.tanh(zr - z * se), np.tanh(zr + z * se)
    
    for label, r, n in [("attendance vs literacy", 0.039, 659),
                        ("literacy vs numeracy", 0.849, 659)]:
        lo, hi = fisher_ci(r, n)
        print(f"{label:24} r = {r:+.3f}  95% CI [{lo:+.3f}, {hi:+.3f}]")
  8. Slide 8 / 29

    An interval on a correlation — In R

    cor.test(joined$attendance, joined$literacy)
  9. Slide 9 / 29

    An interval on a correlation

    • r = 0.039, 95% CI −0.037 to +0.115 — The interval contains zero and every value inside it is negligible, so this is not…
    • A correlation with no interval is the same defect as a proportion with none — and cor.test gives it for free
    Speaker notes
    r = 0.039, 95% CI −0.037 to +0.115. The interval contains zero and every value inside it is negligible, so this is not an underpowered null — 659 students are enough to say that if a relationship exists it is too small to matter. Contrast the same interval on the second pair: r = 0.849, CI 0.826 to 0.869, where the whole interval is large. A correlation with no interval is the same defect as a proportion with none, and cor.test gives it for free.
  10. Slide 10 / 29

    The correlation that is there and says nothing

    • It is one child, one test day, two forty-item papers — A child who was ill, who had not eaten, who could not read the…
    • Ask what would have to be true for the correlation to be zero — Here the answer is "the same child would have to…
    • A correlation is only informative when its absence was plausible — and that is a judgement about the world rather than…
    Speaker notes
    Literacy and numeracy correlate at 0.849, which is the largest r in this course and the least interesting. It is one child, one test day, two forty-item papers. A child who was ill, who had not eaten, who could not read the instructions, or who is simply a strong student scores similarly on both. The correlation is a property of the measurement, not a discovery about literacy and numeracy. Ask what would have to be true for the correlation to be zero. Here the answer is "the same child would have to perform independently on two papers taken half an hour apart", which nobody believes — so a high r carries no information. A correlation is only informative when its absence was plausible, and that is a judgement about the world rather than about the data.
  11. Slide 11 / 29

    Square it before you describe it — In Python

    for label, r in [("attendance vs literacy", 0.039),
                     ("attendance vs literacy, school level", 0.199),
                     ("literacy vs numeracy", 0.849)]:
        print(f"{label:38} r = {r:+.3f}   r-squared = {r**2:.3f}")
  12. Slide 12 / 29

    Square it before you describe it — In R

    # r^2 is the share of variance, and it is much smaller than r looks.
  13. Slide 13 / 29

    Square it before you describe it

    Pairrr²Reads as
    Attendance and literacy0.0390.002Two tenths of one per cent
    Attendance and literacy, school level0.1990.040Four per cent
    Literacy and numeracy0.8490.721Seventy-two per cent
  14. Slide 14 / 29

    Square it before you describe it

    • An r of 0.199 sounds like a relationship and explains four per cent of the variation — Squaring is the cheapest defence…
    Speaker notes
    An r of 0.199 sounds like a relationship and explains four per cent of the variation. Squaring is the cheapest defence against over-reading a middling correlation, and the number to put in a report is usually r² rather than r.
  15. Slide 15 / 29

    Pearson, Spearman, and eleven bad rows — In Python

    wash = pd.read_csv("wash-household-survey-2024.v1.csv")
    pair = wash.dropna(subset=["round_trip_minutes", "litres_per_person_day"])
    clean = pair[pair["litres_per_person_day"] <= 80]
    
    for label, frame in [("all rows", pair), ("11 rows removed", clean)]:
        p = frame["round_trip_minutes"].corr(frame["litres_per_person_day"])
        s = frame["round_trip_minutes"].corr(frame["litres_per_person_day"],
                                             method="spearman")
        print(f"{label:18} n = {len(frame):5}  Pearson {p:+.3f}  Spearman {s:+.3f}")
    Speaker notes
    Lesson 1 found eleven households whose total consumption was entered in a per-person column. Watch what those eleven rows do to a correlation.
  16. Slide 16 / 29

    Pearson, Spearman, and eleven bad rows — In R

    cor(pair$round_trip_minutes, pair$litres_per_person_day)                    # Pearson
    cor(pair$round_trip_minutes, pair$litres_per_person_day, method = "spearman")
  17. Slide 17 / 29

    Pearson, Spearman, and eleven bad rows

    RowsnPearsonSpearman
    All2,403−0.185−0.285
    Eleven removed2,392−0.293−0.287
  18. Slide 18 / 29

    Pearson, Spearman, and eleven bad rows

    • Eleven rows in 2,403 cut Pearson by more than a third. Spearman did not move
    • Report Spearman when either variable is skewed or has outliers you have not resolved, and Pearson when both are roughly…
    • The corrected answer is the useful one — longer trips to water go with less water used, r = −0.29 on 2,392 households,…
    Speaker notes
    Eleven rows in 2,403 cut Pearson by more than a third. Spearman did not move. Pearson uses the values, so a household recorded at 277 litres per person pulls hard on the coefficient. Spearman uses the ranks, so a wrong value that is still the largest value changes nothing. Report Spearman when either variable is skewed or has outliers you have not resolved, and Pearson when both are roughly symmetric and clean. A large gap between the two is a signal to go and look at the extremes — the same use the skewness statistic had in lesson 1. The corrected answer is the useful one: longer trips to water go with less water used, r = −0.29 on 2,392 households, which is the relationship the WASH course predicted and the uncorrected file understated.
  19. Slide 19 / 29

    Correlated because something else moved both — In Python

    prices = pd.read_csv("market-prices-2024.v1.csv")
    wide = prices.pivot_table(index="period", columns="commodity",
                              values="price_htg", aggfunc="mean").sort_index()
    
    print(f"beans and maize, levels:            {wide['beans-black'].corr(wide['maize']):.3f}")
    changes = wide.diff().dropna()
    print(f"beans and maize, month-on-month:    {changes['beans-black'].corr(changes['maize']):.3f}")
  20. Slide 20 / 29

    Correlated because something else moved both — In R

    cor(wide$`beans-black`, wide$maize)
    cor(diff(wide$`beans-black`), diff(wide$maize))
  21. Slide 21 / 29

    Correlated because something else moved both

    • Beans and maize correlate at 0.986 in levels and 0.876 in month-on-month changes — Neither number means the price of…
    • Correlating two series over time will nearly always give a large number — because almost everything trends
    Speaker notes
    Beans and maize correlate at 0.986 in levels and 0.876 in month-on-month changes. Neither number means the price of beans moves the price of maize. Both series carry the same annual inflation and the same lean-season shock, and the correlation is measuring the shock. Correlating two series over time will nearly always give a large number, because almost everything trends. Differencing removes the shared trend and what survives is the shared shock — which is a common cause, and still not a causal link between the two commodities. The epidemiology course made this point with confounding. The correlation coefficient has no way to express it, which is why the sentence beneath it has to.
  22. Slide 22 / 29

    And the clustering from the last lesson — In Python

    by_school = joined.groupby("school_id")[["attendance", "literacy"]].mean()
    print(f"student level  r = {joined['attendance'].corr(joined['literacy']):.3f}  n = {len(joined)}")
    print(f"school level   r = {by_school['attendance'].corr(by_school['literacy']):.3f}  n = {len(by_school)}")
  23. Slide 23 / 29

    And the clustering from the last lesson — In R

    # Same two variables, two units of analysis, two answers.
  24. Slide 24 / 29

    And the clustering from the last lesson

    • 0.039 across 659 students and 0.199 across 24 schools — The school-level figure has an interval from −0.22 to +0.56 on…
    • Say which unit the correlation is between — every time
    Speaker notes
    0.039 across 659 students and 0.199 across 24 schools. The school-level figure has an interval from −0.22 to +0.56 on 24 points, so it establishes nothing either — but it is five times larger, and an analyst who aggregated first and reported r without n would have written a different sentence. Say which unit the correlation is between, every time. "Attendance correlates with literacy at 0.20" is unreadable without knowing whether the rows are children or schools.
  25. Slide 25 / 29

    Write the sentence

    • Not this — "Attendance is correlated with literacy outcomes." True of the school level, false of the student level, and…
    • Nor this — "There is no relationship between attendance and literacy." Stronger than the data supports; the interval…
    • This — "Across 659 students, attendance over the February–April term shows no association with endline literacy (r =…
    • The third sentence is the one to copy — It states the finding, the interval, what it means for the programme, and the…
    Speaker notes
    The coefficient is one number and the sentence beneath it is where the analysis is either honest or not. Not this: "Attendance is correlated with literacy outcomes." True of the school level, false of the student level, and unfalsifiable as written. Nor this: "There is no relationship between attendance and literacy." Stronger than the data supports; the interval reaches +0.12. This: "Across 659 students, attendance over the February–April term shows no association with endline literacy (r = 0.04, 95% CI −0.04 to +0.12). The register cannot support the assumption that attendance drives learning in this cohort. Note that attendance varies little — the middle half of students sit between 86.7% and 97.8% — so this analysis has limited ability to detect a relationship at the low attendance where one would be expected." The third sentence is the one to copy. It states the finding, the interval, what it means for the programme, and the reason the analysis might have missed something real — and it is four lines.
  26. Slide 26 / 29

    Report it whole — Example

    Attendance and learning outcomes, endline 2024
    
      Attendance vs endline literacy   r = 0.04   95% CI -0.04 to +0.12   n = 659
      Attendance vs endline numeracy   r = -0.01  95% CI -0.08 to +0.07   n = 659
    
      Between students within the term. No association at student level.
      Aggregated to the 24 schools, r = 0.20 (95% CI -0.22 to +0.56), which is
      also consistent with no relationship.
    
      Attendance is compressed: the interquartile range is 86.7% to 97.8%, so
      students with the low attendance that a learning effect would show up at
      are rare in this cohort. This is a null result about the range observed,
      not about attendance in general.
  27. Slide 27 / 29

    Report it whole

    • The last paragraph is what stops the null being over-read — and it is the counterpart of the "underpowered, not null"…
    Speaker notes
    The last paragraph is what stops the null being over-read, and it is the counterpart of the "underpowered, not null" sentence from lesson 4. A correlation of zero over a narrow range says nothing about what happens outside it.
  28. Slide 28 / 29

    What comes next

    • The last lesson assembles all of this into the statistics section of a report — what goes in, what stays in the appendix, and what a reviewer will ask for that this course has already computed.
    Speaker notes
    The last lesson assembles all of this into the statistics section of a report — what goes in, what stays in the appendix, and what a reviewer will ask for that this course has already computed.
  29. Slide 29 / 29

    Where this goes next

    Read the full lesson, with runnable code Back to the lesson