Skip to content
Quantitative History Methods

Working with historical price data well comes down to three disciplines: keep the raw source figure untouched, convert currencies and units to documented common standards in separate columns, and never mix nominal and real values in the same calculation. Get those right and your real-price comparisons, index linking and trend charts stay defensible no matter how the project grows. Most published errors in price history trace back to silent unit conversions or a deflator applied at the wrong stage.

Why is historical price data so error-prone?

Three problems compound. First, currency was non-decimal and regional: an English account in pounds, shillings and pence (L-s-d), a price in Flemish groats, a wage in Reichstaler. Second, units drifted, the bushel, the ell, the pound weight all differed by town and century. Third, comparability requires a deflator, and every cost-of-living index embeds assumptions about a typical basket that may not fit your goods. None of these are visible in a single number, so the discipline is to surface them as explicit, cited columns rather than bake them into one value.

How should I structure a price table?

Keep one row per observation and split every transformation into its own column, so you can always trace a real price back to the ink on the page.

columnexamplepurpose
source_amount"3s 4d"verbatim transcription, never edited
amount_pence40integer, smallest unit
currency"GBP"ISO-style code
quantity1how many units bought
unit_raw"bushel"verbatim unit
unit_std"litre"normalised reference
conv_factor36.37documented, with source
year1693for index lookup
real_index"Allen-London"which deflator

The conv_factor and real_index columns are what make the work reproducible. A reviewer can recompute every derived figure from the verbatim columns alone.

Converting non-decimal currency

Store money as a single integer of the smallest unit and only format for display. For L-s-d, total pence = pounds*240 + shillings*12 + pence:

python
def to_pence(pounds=0, shillings=0, pence=0):
    return pounds * 240 + shillings * 12 + pence

def from_pence(total):
    p, rem = divmod(total, 240)
    s, d = divmod(rem, 12)
    return f"{p}L {s}s {d}d"

to_pence(0, 3, 4)   # -> 40

Integer pence sort and sum correctly; never average L-s-d as floating-point pounds.

Nominal versus real: where does the deflator go?

Compute everything in nominal terms first, aggregate, then deflate the aggregate. Deflating each line before summing multiplies index error through your whole series. The real price is simply nominal / index * 100 against a base year:

python
real = nominal_pence / cpi_year * cpi_base

If sources span different currencies, convert to one currency using a contemporary exchange rate before any aggregation, and record that rate as its own column too.

How do I choose and cite a deflator?

Pick a published index built for your region and period, the Allen welfare-ratio baskets, a national consumer-price series, or a commodity-specific index, and record three things: the index name, its base year, and where you got it. The choice changes your conclusions, so it must be visible. A grain study deflated by a general cost-of-living index will understate food inflation during dearth years; prefer a food-weighted basket when your goods are food.

What about seasonality and gaps?

Grain and food prices swing with the harvest, so monthly comparisons need seasonal adjustment or, more honestly, a note of which months each annual figure covers. For gaps, never interpolate silently; flag interpolated values in a is_estimated boolean column so downstream charts can render them differently. A dashed line for estimated stretches communicates uncertainty better than a smooth, falsely confident curve.

A working checklist

  1. Transcribe the source figure and unit verbatim into untouched columns.
  2. Convert currency to integer smallest-units on import.
  3. Add normalised units with a cited conversion factor.
  4. Aggregate in nominal terms, then deflate the aggregate.
  5. Record index name, base year and source for every real price.
  6. Flag estimated and interpolated values explicitly.
  7. Note the months covered for any annual or sub-annual figure.

Key Takeaways

  • Keep the verbatim source amount and unit in columns you never edit.
  • Store money as integer smallest-units (total pence) to avoid rounding.
  • Aggregate nominal first, then deflate the aggregate, never per-line.
  • Always cite the deflator's name, base year and source.
  • Document every unit conversion factor with its provenance.
  • Flag estimated, interpolated and seasonally sensitive values.
  • A real price you cannot trace back to the page is not reproducible.

Frequently Asked Questions

Should I deflate historical prices before or after aggregating?

Aggregate nominal prices first, then deflate the aggregate, unless your sources use different currencies or units, in which case convert to a common unit before any arithmetic. Deflating per-record before summing compounds index error into every line.

What is the difference between nominal and real prices?

Nominal prices are the figures as written in the source; real prices express them in the purchasing power of a single base year using a price index. Real prices let you compare across decades, but they inherit all the uncertainty of the index you chose.

Which price index should I use for early modern data?

Use a published cost-of-living or commodity basket index built for your region and period, such as the Allen welfare-ratio baskets or national consumer price series. Always cite the index, its base year and its source weights so others can reproduce your real-price calculation.

How do I handle non-decimal currencies like pounds, shillings and pence?

Convert every amount to a single smallest unit (total pence) on import, store that integer, and only format back to L-s-d for display. This avoids rounding errors and makes sorting and arithmetic trivial.

How should I store units of measure that changed over time?

Record the raw unit string exactly as written, then add a separate normalised column converting to a modern reference unit with a documented conversion factor. Never overwrite the original, because local bushels and ells varied by town and decade.

Do I need to adjust for seasonality in price series?

Yes, if your data is monthly or quarterly and you are comparing within-year movements; grain and food prices swing sharply by harvest cycle. For annual averages built from many months, seasonality largely cancels but you should still note the months covered.