Where New Zealand’s sheep went

A regional breakdown of the flock decline, 2002–2025

Author

Feng Jiang

Published

September 4, 2026

Source data: Stats NZ, Agricultural production statistics, licensed by Stats NZ for re-use under the Creative Commons Attribution 4.0 International licence.

The short version

New Zealand’s sheep flock fell by 16.32 million between June 2002 and June 2025, a drop of 41 percent.

Three points, each with one number.

  • Three regions — Canterbury, Southland, Otago — account for 54 percent of the total fall, across the 15 regions where both endpoints are published.
  • Over the same 23 years the national dairy herd grew by only 588 thousand cattle, while beef cattle fell by 659 thousand.
  • In 7 of the 13 regions where both series are published, dairy cattle fell alongside sheep rather than in place of them.

What this means

The common story is that sheep farms became dairy farms. At a national level the arithmetic does not support that story. Sheep numbers fell by roughly 16 million head. Dairy cattle rose by roughly six hundred thousand. Those are different orders of magnitude.

The picture changes region by region. Canterbury and Southland did add dairy cattle on a scale worth noticing. Most other regions that lost sheep did not, and several lost dairy cattle as well. Whatever replaced the sheep, in most of the country it was not another animal counted in this table.

What these numbers do not tell you

They are head counts. They say nothing about land area, feed demand, grazing pressure, farm profitability, or what the land is used for now. A dairy cow and a sheep are not exchangeable units, and this page does not treat them as such.

The regional breakdown

Show the code
plot_dat <- sheep_change |>
  filter(!is.na(change)) |>
  mutate(region = factor(region, levels = rev(region)),
         millions = -change / 1e6)

p1 <- ggplot(plot_dat, aes(x = millions, y = region)) +
  geom_col(fill = "#2d6a4f", width = 0.72) +
  geom_text(aes(label = sprintf("%.2f", millions)),
            hjust = -0.15, size = 3.1, colour = "grey25") +
  annotate("label", x = max(plot_dat$millions) * 0.45,
           y = 4.2,
           label = sprintf("%s\naccount for %.0f%% of the fall",
                           paste(top3$region, collapse = ", "), top3_share),
           hjust = 0, size = 3.4, label.size = 0, fill = "grey96", colour = "grey20") +
  scale_x_continuous(labels = label_comma(accuracy = 0.1),
                     expand = expansion(mult = c(0, 0.14))) +
  labs(
    title    = "Three South Island regions account for over half the national fall",
    subtitle = "Reduction in sheep numbers, millions of head, June 2002 to June 2025",
    x = "Million head fewer", y = NULL,
    caption  = "Source: Stats NZ, Agricultural production statistics.\nLicensed by Stats NZ for re-use under CC BY 4.0."
  ) +
  theme_minimal(base_size = 12) +
  theme(panel.grid.major.y = element_blank(),
        panel.grid.minor   = element_blank(),
        plot.title.position = "plot",
        plot.title    = element_text(face = "bold"),
        plot.caption  = element_text(colour = "grey45", hjust = 0, size = 8))

ggsave("outputs/figures/01-regional-contribution.png", p1,
       width = 9, height = 6, dpi = 200, bg = "white")
p1
Horizontal bar chart of 15 regions ordered by how many sheep they lost between 2002 and 2025. Canterbury is largest at 3.57 million head fewer, then Southland at 2.91 million and Otago at 2.27 million; together these three make up just over half the national fall. The remaining regions range from Manawatū-Whanganui at 2.25 million down to the Chatham Islands at 0.01 million.
Figure 1: Contribution of each region to the national fall in sheep numbers, June 2002 to June 2025.

Two regions are missing from that chart. Auckland and Nelson have a suppressed 2025 value, so no change can be computed for them. They are excluded and counted, never imputed and never set to zero.

Did dairy replace the sheep?

Show the code
dumb <- substitution |>
  filter(region %in% top5_regions) |>
  pivot_longer(-region, names_to = "livestock_class", values_to = "change") |>
  mutate(
    region = factor(region, levels = rev(top5_regions)),
    livestock_class = factor(livestock_class,
                             levels = c("Sheep", "Dairy cattle", "Beef cattle")),
    thousands = change / 1e3
  )

p2 <- ggplot(dumb, aes(x = thousands, y = region)) +
  geom_vline(xintercept = 0, colour = "grey60") +
  geom_line(aes(group = region), colour = "grey75", linewidth = 0.8) +
  # Shape as well as colour, so colour is not the only channel carrying the
  # distinction. The green and the red-brown are close under red-green colour
  # vision deficiency; WCAG 1.4.1 asks that colour not be used alone.
  geom_point(aes(colour = livestock_class, shape = livestock_class), size = 3.4) +
  scale_colour_manual(values = c("Sheep" = "#2d6a4f",
                                 "Dairy cattle" = "#c1666b",
                                 "Beef cattle" = "#4a6fa5"), name = NULL) +
  scale_shape_manual(values = c("Sheep" = 16, "Dairy cattle" = 17,
                                "Beef cattle" = 15), name = NULL) +
  scale_x_continuous(labels = label_comma(), expand = expansion(mult = 0.07)) +
  labs(
    title    = "Where sheep left, cattle mostly did not arrive in comparable numbers",
    subtitle = "Change in animals, thousands of head, June 2002 to June 2025, five largest sheep declines",
    x = "Thousand head, change over the period", y = NULL,
    caption  = "Source: Stats NZ, Agricultural production statistics.\nLicensed by Stats NZ for re-use under CC BY 4.0."
  ) +
  theme_minimal(base_size = 12) +
  theme(panel.grid.major.y = element_blank(),
        panel.grid.minor   = element_blank(),
        legend.position    = "top",
        plot.title.position = "plot",
        plot.title   = element_text(face = "bold"),
        plot.caption = element_text(colour = "grey45", hjust = 0, size = 8))

ggsave("outputs/figures/02-substitution.png", p2,
       width = 9, height = 5.5, dpi = 200, bg = "white")
p2
Dot chart for the five regions with the largest sheep declines. In each region the sheep marker sits far to the left of zero, between 1.3 and 3.6 million head fewer, while the dairy and beef cattle markers sit close to zero. Canterbury has the largest dairy gain at about 795 thousand and Southland about 281 thousand; in Hawke's Bay and Manawatū-Whanganui both cattle markers fall below zero, meaning cattle declined as well.
Figure 2: Change in sheep, dairy cattle and beef cattle in the five regions that lost the most sheep.

Stated plainly, per hundred sheep lost:

Show the code
substitution |>
  filter(region %in% top5_regions) |>
  transmute(
    Region = region,
    `Sheep lost` = fmt(-Sheep),
    `Dairy cattle per 100 sheep lost` = sprintf("%+.1f", -100 * `Dairy cattle` / Sheep),
    `Beef cattle per 100 sheep lost`  = sprintf("%+.1f", -100 * `Beef cattle` / Sheep)
  ) |>
  kable(align = "lrrr")
Table 1
Region Sheep lost Dairy cattle per 100 sheep lost Beef cattle per 100 sheep lost
Canterbury 3,565,643 +22.3 +1.7
Otago 2,270,557 +3.5 +2.2
Southland 2,906,676 +9.7 +0.1
Hawke’s Bay 1,331,249 -1.9 -7.7
Manawatū-Whanganui 2,254,586 +0.9 -6.6

Canterbury accounts for by far the largest absolute dairy increase of any region, at 795 thousand head. It is not, however, the highest ratio: West Coast gained 39 dairy cattle per 100 sheep lost, on a base so small — under 40 thousand sheep — that the ratio says more about the denominator than about land use. Hawke’s Bay and Manawatū-Whanganui lost sheep and cattle. A negative figure in this table means that class of animal declined as well.

Data quality checks

Five rules run over the analysis table on every render.

Show the code
kable(results, align = "lrrrr")
Table 2
rule items passes fails nNA
head_non_negative 1397 1397 0 0
value_iff_suppressed 1397 1397 0 0
region_label_present 1397 1397 0 0
no_duplicate_cells 1397 1397 0 0
census_year_reported 1397 1388 9 0

Four pass. The fifth fires 9 times, and that is a finding rather than a defect. census_year_reported asserts that a census year — a full-coverage collection, with no sampling error to exceed a threshold — should not have withheld cells. It is wrong. Census years do withhold cells, because withholding is about confidentiality and imputation quality, not about coverage. The rule earns its place by being falsified.

Showing that the rules can fail

An all-green table is not evidence. A reader cannot tell from it whether the rules are sound or merely too loose to fire. So the same five rules are also run against a deliberately corrupted copy of the analysis table: one negative count, one withheld cell filled with a zero, one census-year value removed, one region label deleted, and one duplicated row.

Show the code
results |>
  select(rule, `real data` = fails) |>
  left_join(select(results_corrupted, rule, `corrupted copy` = fails),
            by = "rule") |>
  kable(align = "lrr", col.names = c("Rule", "Fails on real data",
                                     "Fails on corrupted copy"))
Table 3
Rule Fails on real data Fails on corrupted copy
head_non_negative 0 1
value_iff_suppressed 0 1
region_label_present 0 1
no_duplicate_cells 0 2
census_year_reported 9 10

Each corruption moves exactly one rule. no_duplicate_cells moves by two because a duplicate makes both members of the pair non-unique, and census_year_reported moves from 9 to 10 because it already fails nine times on the real data. The corrupted rows are chosen at distinct indices and the function asserts as much, so no single corruption can be counted twice.

That is what makes the left-hand column mean something: the zeroes are the result of rules that demonstrably fire when there is something to fire at.

The more interesting result is in the reconciliation: the published national total against the sum of the regions.

Show the code
reconciliation |>
  filter(livestock_class == "Sheep") |>
  left_join(select(coverage, year, regions_present, regions_suppressed), by = "year") |>
  transmute(
    Year = year,
    `Regions published` = regions_present,
    `Regions suppressed` = regions_suppressed,
    `Sum of regions` = fmt(region_sum),
    `Published national` = fmt(published),
    `Residual (head)` = fmt(residual),
    `Residual %` = sprintf("%.3f", residual_pct)
  ) |>
  kable(align = "rrrrrrr")
Table 4
Year Regions published Regions suppressed Sum of regions Published national Residual (head) Residual %
2002 17 0 39,571,837 39,571,837 0 0.000
2003 15 0 39,408,419 39,552,113 143,694 0.363
2004 15 0 39,198,830 39,271,137 72,307 0.184
2005 16 0 39,824,732 39,879,668 54,936 0.138
2006 15 0 39,980,941 40,081,594 100,653 0.251
2007 17 0 38,460,477 38,460,477 0 0.000
2008 16 0 33,767,565 34,087,864 320,299 0.940
2009 16 0 32,312,249 32,383,589 71,340 0.220
2010 17 0 32,562,612 32,562,612 0 0.000
2011 17 0 31,132,328 31,132,329 1 0.000
2012 17 0 31,262,715 31,262,715 0 0.000
2013 17 0 30,786,762 30,786,761 -1 -0.000
2014 17 0 29,803,402 29,803,402 0 0.000
2015 17 0 29,120,829 29,120,827 -2 -0.000
2016 17 0 27,583,672 27,583,673 1 0.000
2017 17 1 27,506,969 27,526,537 19,568 0.071
2018 17 2 27,202,153 27,295,749 93,596 0.343
2019 17 2 26,535,840 26,821,846 286,006 1.066
2020 17 1 26,008,537 26,028,935 20,398 0.078
2021 17 4 25,174,579 25,732,889 558,310 2.170
2022 17 1 25,113,843 25,132,697 18,854 0.075
2023 17 1 24,338,666 24,359,267 20,601 0.085
2024 17 1 23,363,016 23,583,001 219,985 0.933
2025 17 2 22,997,178 23,252,463 255,285 1.098

The residual column is reported in head as well as in percent on purpose. At a base of 30 million, a percentage rounded to three decimal places renders a discrepancy of one animal as 0.000, which would let the table appear to support a stronger claim than the numbers do.

Across all three livestock classes the residual separates into three tiers.

Show the code
residual_tiers |>
  count(tier, name = "Class-years") |>
  left_join(
    residual_tiers |>
      group_by(tier) |>
      summarise(`Largest absolute residual (head)` = fmt(max(abs(residual))),
                .groups = "drop"),
    by = "tier"
  ) |>
  rename(Tier = tier) |>
  kable(align = "lrr")
Table 5
Tier Class-years Largest absolute residual (head)
Exact 10 0
Fully published, off by a few head 12 2
Incomplete region row 50 701,526

In the 10 class-years where all seventeen regions are published and nothing is withheld, the regions sum to the published national total exactly, to the head.

Completeness is the criterion for these tiers, not the residual. That matters here: 11 class-years reconcile to zero, one more than the Exact tier contains, because one class-year with an incomplete region row happens to reconcile exactly anyway.

In 12 further fully-published class-years the residual never exceeds 2 head, on bases between 3.5 and 31.1 million. I cannot attribute that from published data. It is consistent with the national aggregate being rounded independently of the regional cells, but I have not been able to source that and do not assert it. Nor can I rule out input perturbation: only two fully-published class-years fall after 2017, when perturbation was introduced, which is far too few to say anything either way.

Every residual larger than that — and the next smallest is 507 head — belongs to a year whose region row is incomplete, because a region is withheld or because a region code is absent from that year’s table.

What the one-head residuals are not is an artefact of this analysis. The same discrepancy appears between cells that this analysis never sums. Adding the two published island totals and comparing them against the published national total — three aggregate cells, always published, never withheld — gives a difference of one head in 14 of the 72 class-years, and never more than 1.

Show the code
island_reconciliation |>
  filter(residual != 0) |>
  transmute(
    Year = year,
    Class = livestock_class,
    `North Island` = fmt(a10),
    `South Island` = fmt(a19),
    `Sum` = fmt(a10 + a19),
    `Published NZ` = fmt(a20),
    `Difference` = fmt(residual)
  ) |>
  kable(align = "rlrrrrr")
Table 6
Year Class North Island South Island Sum Published NZ Difference
2003 Beef cattle 3,400,859 1,225,759 4,626,618 4,626,617 -1
2005 Beef cattle 3,249,727 1,173,898 4,423,625 4,423,626 1
2006 Beef cattle 3,258,533 1,180,602 4,439,135 4,439,136 1
2014 Beef cattle 2,604,422 1,065,439 3,669,861 3,669,862 1
2018 Beef cattle 2,620,089 1,101,174 3,721,263 3,721,262 -1
2019 Beef cattle 2,707,287 1,182,710 3,889,997 3,889,996 -1
2020 Beef cattle 2,636,865 1,245,702 3,882,567 3,882,566 -1
2023 Beef cattle 2,501,041 1,152,992 3,654,033 3,654,034 1
2004 Dairy cattle 3,787,210 1,365,281 5,152,491 5,152,492 1
2005 Dairy cattle 3,731,709 1,355,468 5,087,177 5,087,176 -1
2009 Dairy cattle 3,796,485 2,064,292 5,860,777 5,860,776 -1
2018 Dairy cattle 3,816,099 2,569,441 6,385,540 6,385,541 1
2004 Sheep 18,734,141 20,536,997 39,271,138 39,271,137 -1
2009 Sheep 16,077,872 16,305,716 32,383,588 32,383,589 1

So the one-head discrepancies are a property of the published table, not of the join. That does not explain them, but it does locate them.

Suppression is not constant over time

Show the code
p3 <- ggplot(supp_by_code, aes(x = year, y = rate)) +
  geom_col(aes(fill = label), width = 0.7) +
  scale_fill_manual(values = c("C - confidentiality (pre-2017 method)" = "#e07a5f",
                               "S - quality suppression" = "#6c8ea4"), name = NULL) +
  scale_x_continuous(breaks = seq(2002, 2025, 3), limits = c(2001, 2026)) +
  scale_y_continuous(labels = label_percent(scale = 1)) +
  guides(fill = guide_legend(nrow = 2)) +
  labs(
    title    = "Two different flags, two different stories",
    subtitle = "Percentage of region-by-livestock-class cells withheld: sheep, dairy and beef cattle",
    x = NULL, y = "Cells suppressed",
    caption  = "Source: Stats NZ, Agricultural production statistics.\nLicensed by Stats NZ for re-use under CC BY 4.0."
  ) +
  theme_minimal(base_size = 12) +
  theme(panel.grid.major.x = element_blank(),
        panel.grid.minor   = element_blank(),
        legend.position    = "top",
        plot.title.position = "plot",
        plot.title   = element_text(face = "bold"),
        plot.caption = element_text(colour = "grey45", hjust = 0, size = 8))

ggsave("outputs/figures/03-suppression-rate.png", p3,
       width = 9, height = 5, dpi = 200, bg = "white")
p3
Bar chart of the percentage of regional cells withheld each year from 2002 to 2025, coloured by flag. Nothing is withheld from 2002 to 2011. A single orange bar in 2012 marks the C confidentiality flag at about 8 percent. Blue bars for the S quality-suppression flag begin in 2014 and run to 2025, peaking near 18 percent in 2021, with the census years 2017 and 2022 lower than the survey years around them.
Figure 3: Share of regional cells withheld, by year and by flag.

Reading that chart as a single rising trend would be wrong, and the OBS_STATUS column is what makes the difference visible. Two flags are in use, and they are not the same mechanism.

The C flag is confidentiality suppression. Among the three livestock classes used here it appears in 2012 and in no other year. Checked across every one of the 44 livestock codes in the raw extract, it appears in 2012–2016 and never after 2016.

That is exactly what the published methodology predicts. Stats NZ states that prior to 2017, figures affected by the confidentiality provisions were denoted by C, and that since 2017 confidentiality has instead been implemented by an input perturbation method that adds noise at individual farm level, so output figures no longer have to be replaced with C. The flag stops in the file in the same year the method changed.

The S flag is quality suppression, applied where sampling errors or imputation levels are high. It runs from 2014 to 2025, peaking at 17.6 percent of cells in 2021. The census years 2017 and 2022 sit below the survey years around them — but not at zero, and the difference between those two statements is the mechanism.

The published rule withholds data with high sample errors or high imputation levels. A census removes the first branch, which is why census years sit lower. The second branch remains, which is why they are not empty. All 5 census-year S cells in this table are Nelson.

So the 2012 spike is not a quality problem at all. All 4 withheld cells that year carry C, not S. Separating the two flags turns an apparent anomaly into the expected behaviour of a confidentiality rule that was replaced in 2017.

One qualification remains. I cannot tell from this extract whether the absence of any flag before 2012 means no cell was withheld, or that the flag was not carried in this export. The chart shows what the file contains.

One of the two regions this analysis has to drop is explained in the published methodology rather than guessed at. Sampling error could not be calculated for Nelson because only one responding unit was observed in each sampled stratum, and at least two are needed to estimate a within-stratum variance. Auckland, the other dropped region, is simply withheld, with no reason published.

Independent recomputation

Stats NZ publishes a national sheep figure for June 2024. Recomputing it from the regional cells in the same extract gives a different number, and the difference is fully explained.

Show the code
r24 <- reconciliation |> filter(livestock_class == "Sheep", year == 2024)
data.frame(
  Quantity = c("Published, Total New Zealand, June 2024",
               "Recomputed as the sum of published regions",
               "Difference"),
  Head = c(fmt(r24$published), fmt(r24$region_sum), fmt(r24$residual))
) |> kable(align = "lr")
Table 7
Quantity Head
Published, Total New Zealand, June 2024 23,583,001
Recomputed as the sum of published regions 23,363,016
Difference 219,985

The difference is Auckland, whose 2024 value is suppressed. Filling it with zero would have produced a total that looked tidier and was wrong by 219,985 head.

Method

  1. One table, one vintage. Stats NZ table AGR_AGR_003, Livestock Numbers by Regional Council, dataflow STATSNZ:AGR_AGR_003(1.0), final vintage, downloaded once and committed with its SHA-256. Full provenance is in data-raw/SOURCE.md.
  2. Codes verified before code was written. The extract carries numeric codes and no labels. Sheep, dairy cattle and beef cattle were each confirmed against the published June 2024 national figures before any analysis was run. The LIVESTOCK codelist holds 44 entries that nest inside one another; adding all 44 for 2024 gives 115.7 million animals against a published 33.8 million. Only the three verified codes are used.
  3. Aggregates are separated, not summed. AREA codes 10, 19 and 20 are the North Island, South Island and New Zealand totals. They are flagged in the analysis table and excluded from every regional sum. The extract publishes no area labels at all, only numeric codes; region names here follow the Statistical standard for geographic areas 2023 (SSGA23), including macrons, which differ from the older spellings the codelist still displays in Aotearoa Data Explorer.
  4. Suppressed cells stay suppressed. A suppressed cell becomes NA and carries a flag. It is never filled with zero and never dropped. Regions missing either endpoint are excluded from the change calculation and counted in the text.
  5. Reconciliation is reported, not asserted. No fixed tolerance is set between the regional sum and the published total. The residual is computed for every year and published above.
  6. Quantitative claims are computed, cited, or explicitly rounded — and the three are different things. Numbers that come from the data are inline expressions evaluated at render time against the analysis table, never transcribed. Numbers that come from Stats NZ’s published methodology — sample size, eligible population, response rate, imputation level, relative sampling error, the GST threshold, the codelist totals — cannot be computed from an aggregate extract; they are typed, and each is attributed under Sources for the methodological statements. Numbers in the plain-language layer at the top are deliberately rounded, with the exact value always available further down. Qualitative claims are stated with the scope over which they were checked. Earlier versions of this page each carried a universal claim that was typed rather than computed, and each was contradicted by a table printed directly beneath it; this is the rule that came out of that, including the version of this rule that claimed every number on the page was computed, which was itself false.

Release schedule

This analysis uses the final vintage throughout. Up to and including the 2024 survey, Stats NZ published a provisional release in mid-December and a final release in mid-May of the following year. From the 2025 survey those two were replaced by a single final release in mid-April.

Survey design

The reference period is the year ended 30 June. Censuses were held in 2002, 2007, 2012, 2017 and 2022, with annual sample surveys in the intervening years. The sample is stratified by regional council area, ANZSIC06 group and size group. The 2025 survey drew 24,600 geographic locations from an estimated eligible population of 45,800; note that a geographic location is the statistical unit and is not the same thing as a farm.

The series starts at 2002 because Stats NZ states that the population for the 2002 census and subsequent surveys differs from that of earlier agricultural censuses and surveys, and that figures from 2002 onward may not be directly comparable with previous years. That is also why the 1994 observation carried in the same table is excluded here. There was no agricultural production survey at all in 1997, 1998 or 2001.

Values for non-respondents are imputed by random hot deck imputation, with the imputation class formed from regional council area, ANZSIC06 group and production data from previous years. This matters more than it may appear: for the 2025 survey Stats NZ reports that 30 percent of the total sheep estimate was imputed, against a relative sampling error of 3 percent at 95 percent confidence. The response rate for the 2025 final release was 72.1 percent. The collection is run by Stats NZ in partnership with the Ministry for Primary Industries.

The headline window is not design-matched

2002 is a census and 2025 is a sample survey, so the headline differences a full-coverage count against an estimate that carries both sampling error and a 30 percent imputation rate. This is a common and accepted comparison — Stats NZ publishes the series as one — but it is an asymmetry, and this report carries the is_census_year flag through the analysis table precisely so that it can be checked rather than assumed.

The census-to-census window that avoids the asymmetry is 2002 to 2022:

Show the code
rbind(
  data.frame(Window = "2002–2025, census to sample survey (headline)",
             Regions = sensitivity$regions[sensitivity$start == 2002],
             Fall = fmt(sensitivity$fall[sensitivity$start == 2002]),
             `Top three share` = sprintf("%.1f%%", sensitivity$share[sensitivity$start == 2002]),
             `The three regions` = sensitivity$top3[sensitivity$start == 2002],
             check.names = FALSE),
  data.frame(Window = "2002–2022, census to census (design-matched)",
             Regions = matched$regions,
             Fall = fmt(matched$fall),
             `Top three share` = sprintf("%.1f%%", matched$share),
             `The three regions` = matched$top3,
             check.names = FALSE)
) |> kable(align = "lrrrl")
Table 8
Window Regions Fall Top three share The three regions
2002–2025, census to sample survey (headline) 15 16,195,353 54.0% Canterbury, Southland, Otago
2002–2022, census to census (design-matched) 16 14,446,905 55.6% Canterbury, Southland, Manawatū-Whanganui

The design-matched window is measurable across one more region, because Auckland is published in 2022 and withheld in 2025. It gives the same qualitative answer: a fall of 14.4 million head with the three largest decliners accounting for 55.6 percent.

The 2025 endpoint is used in the headline because it is the most recent published figure, not because it is the better-matched one.

What was excluded, and why

  • Territorial authority geography — the surveys are designed to produce results to regional council level and the censuses to territorial authority level, so no annual series exists below the region.
  • Horticulture — not collected in 2004, 2006, 2008, 2010, 2013, 2015, 2016, 2018, 2021, 2023 or 2025, which is most of this window.
  • Forestry production — Stats NZ no longer collects or compiles forestry production statistics; they are published by MPI. Stats NZ does still collect forestry land use. The 2025 release also notes that additional National Exotic Forest Description data has been received and that revisions to earlier land use and forestry statistics, especially for 2016 to 2021, are planned.
  • Pre-2002 data — the population change described above, plus the absence of any survey in 1997, 1998 and 2001.
  • A choropleth map — a sorted bar chart answers “which regions contributed most” and a map does not, because a map encodes land area rather than magnitude. Canterbury, Otago and Southland are also three of the largest regions by area, which is precisely the confound a map would introduce.
  • A second data set — the question is answerable inside one table, and every extra source adds provenance to defend without adding evidence.

Implications for output design

Three observations follow from the checks above, and they concern the shape of the output rather than the sheep.

Regional council is the only geography available annually; territorial authority exists only in census years, so any sub-regional time series is structurally unavailable rather than merely unpublished. Suppression now runs above ten percent of cells, and it is not spread evenly. Nelson and the Chatham Islands account for 56 percent of every withheld cell in this table between them, Auckland for a further 10 percent, and 7 other regions for the rest.

Two different grounds are at work, and it is worth separating them. Nelson and the Chathams are withheld persistently — they hold the two smallest sheep populations in the table — which makes their trends unusable. Auckland is withheld only at scattered points including the 2025 endpoint, which is what removes it from this analysis’ change calculation while leaving most of its series intact. Auckland is not a small region, and by sheep it is not even among the smallest: its last published count is larger than Northland’s or West Coast’s. Being withheld and being small are related here but not the same thing, and an output that conflated them would mislead.

A suppression-aware grouping that pooled the persistently withheld regions would preserve more signal than withholding them one at a time does. And the alternating census-and-survey design makes every regional series in this table structurally uneven, which belongs on the output rather than being left for a user to discover from a reconciliation residual.

There is also a class of question this data cannot answer at all: anything at farm level, or any breakdown finer than what is published. The access route for those questions is approved microdata under the Five Safes framework, which I have not used here.

Sources for the methodological statements

Every statement about the collection above was read on the page cited here, not carried over from secondary summaries.

Statement Source
Census years 2002, 2007, 2012, 2017, 2022; sample surveys in between; eligible population 45,800 and sample 24,600 geographic locations; stratification by regional council, ANZSIC06 group and size group; 2025 response rate 72.1 percent; sampling error and imputation levels by line code; GST registration level of $60,000 giving “partial and unquantifiable” coverage below it; random hot deck imputation and imputation class; C before 2017 and input perturbation since; S for data with high sample errors or imputation levels; Nelson variance not estimable; horticulture years; forestry production now MPI; Tier 1 statistics Agricultural Production Statistics: June 2025 (Final), DataInfo+
Programme run in partnership with MPI; provisional mid-December plus final mid-May up to 2024, single final mid-April from 2025; 2002 population differs from earlier collections; no survey in 1997, 1998, 2001; regional council annually and territorial authority in censuses Agriculture Production Statistics series, DataInfo+
Release date of 16 April 2026 for the year to June 2025; NEFD data and planned revisions for 2016–2021 Agricultural production statistics: Year to June 2025
Mana Ōrite Relationship Agreement signed with the Data Iwi Leaders Group of the National Iwi Chairs Forum on 30 October 2019 Mana Ōrite Relationship Agreement

Statements I could not source on those pages are not made anywhere in this report. Pages read 4 September 2026.

Limitations

  • Non-census years are sample estimates. I have not recomputed their sampling errors and I have applied no weighting of my own. A year-on-year movement in a single small region should not be read as real change.
  • Suppressed cells are retained as NA and counted. Two regions are excluded from the 2002–2025 change entirely for that reason.
  • The sheep-to-cattle comparisons are ratios of head counts. They are not claims about stocking rate, feed demand, land use or emissions.
  • The frame is Stats NZ’s Business Register, which is built on GST registration. The compulsory registration level is $60,000, and Stats NZ describes coverage of units below that level as “partial and unquantifiable”.
  • Imputation is large. Stats NZ reports 30 percent of the 2025 total sheep estimate as imputed. Every regional figure in a survey year carries that, and this analysis does nothing to correct for it.
  • Since 2017, confidentiality has been implemented by input perturbation, which adds noise at individual farm level. It is small relative to the effects discussed here, but it is present in every year from 2017 on.
  • The endpoints are of different collection designs. 2002 is a census and 2025 is a sample survey. The is_census_year flag is carried through the analysis table for exactly this reason, and the design-matched comparison is reported under Survey design.
  • Choosing the start year is a choice, and the two halves of the headline survive it differently. See the sensitivity analysis below.

How much does the start year matter?

Recomputing the headline statistic from every start year that leaves a window of at least 5 years — 2002 to 2020 — against the same 2025 endpoint. The extract reaches 2025, so 2021 onwards are start years too; they are left out because a four-year window is not a decline window, and the top-three share stops meaning much once the fall it divides is small:

Show the code
sensitivity |>
  transmute(
    `Start year` = ifelse(start %in% CENSUS_YEARS,
                          paste0(start, " (census)"), as.character(start)),
    `Regions measurable` = regions,
    `Fall (head)` = fmt(fall),
    `Top three share` = sprintf("%.1f%%", share),
    `The three regions` = top3
  ) |>
  kable(align = "lrrrl")
Table 9
Start year Regions measurable Fall (head) Top three share The three regions
2002 (census) 15 16,195,353 54.0% Canterbury, Southland, Otago
2003 14 16,098,121 54.6% Canterbury, Southland, Manawatū-Whanganui
2004 14 15,924,689 52.0% Canterbury, Southland, Otago
2005 14 16,540,440 52.9% Canterbury, Southland, Manawatū-Whanganui
2006 14 16,738,228 52.1% Canterbury, Southland, Manawatū-Whanganui
2007 (census) 15 15,168,071 52.9% Canterbury, Southland, Manawatū-Whanganui
2008 14 10,700,360 48.3% Canterbury, Southland, Manawatū-Whanganui
2009 14 9,111,028 48.3% Southland, Manawatū-Whanganui, Otago
2010 15 9,329,065 48.4% Southland, Manawatū-Whanganui, Otago
2011 15 7,919,219 52.4% Manawatū-Whanganui, Canterbury, Otago
2012 (census) 15 8,053,801 51.0% Otago, Southland, Manawatū-Whanganui
2013 15 7,590,781 52.5% Otago, Southland, Manawatū-Whanganui
2014 15 6,581,367 55.9% Otago, Southland, Manawatū-Whanganui
2015 15 5,902,153 59.4% Otago, Manawatū-Whanganui, Southland
2016 15 4,408,959 53.7% Otago, Manawatū-Whanganui, Southland
2017 (census) 15 4,268,875 57.0% Southland, Manawatū-Whanganui, Otago
2018 13 4,108,545 55.5% Otago, Manawatū-Whanganui, Southland
2019 14 3,608,010 53.7% Otago, Manawatū-Whanganui, Hawke’s Bay
2020 14 2,939,552 58.3% Otago, Manawatū-Whanganui, Canterbury

Fall here is measured across the regions listed as measurable in each window, not against the published national total. The two differ by the withheld regions: for 2002–2025 the regional figure is 16,195,353 head against a published national fall of 16,319,374, a gap of 0.77 percent, as set out at the top of this page.

The concentration is robust. Across all 19 start years the three largest-declining regions account for between 48 and 59 percent of the fall, and the range is narrow enough that no start year would change the headline claim.

Which three regions they are is not robust. Manawatū-Whanganui is in the top three in 17 of the 19 windows, Otago in 14, Southland in 16, and Canterbury in only 9 — 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2011, 2020. Canterbury dominates the window this report uses because its decline is concentrated in the early years; from a start year of 2009 or later it usually drops out of the top three altogether.

That is worth stating plainly, because Canterbury is the region this report names most often. It leads the 2002–2025 window, and it is the one region where the substitution story carries weight. It is not a permanent feature of the data.

Ethics

This analysis uses published regional aggregates only. No microdata and no IDI access is involved, so the Five Safes framework does not apply to it.

Stats NZ lists Tatauranga Umanga Māori among the internal users of this collection, and signed the Mana Ōrite Relationship Agreement with the Data Iwi Leaders Group of the National Iwi Chairs Forum in October 2019. Any Māori-specific cut of this data therefore sits inside an established relationship between Stats NZ and iwi Māori. It does not sit with an unaffiliated analyst working from published aggregates, which is why this report does not attempt one and does not characterise the terms of that agreement.

Reproduce

Two steps, because they write different things.

Rscript R/checks.R    # regenerates outputs/*.csv: validation, coverage, reconciliation
quarto render         # regenerates this page and outputs/figures/*.png

R/load.R verifies the extract against the SHA-256 recorded in data-raw/SOURCE.md before reading it, then tidies it; R/checks.R runs the rules and both reconciliations; index.qmd produces this page and the figures.

Both sets of outputs are committed. A clean checkout that runs the two commands above must reproduce the CSVs byte for byte. The figures are regenerated as well, but their bytes can differ with the platform’s fonts and graphics device, so they are not compared. If the extract were ever replaced without SOURCE.md being updated, R/load.R stops rather than analysing it.

That claim is checked rather than asserted. A GitHub Actions job runs both commands on a clean Ubuntu runner on every push, fails if any committed CSV differs, and publishes this page from the same run — so what you are reading is the output of a build that passed.

It earned its place on the first run, by failing. The extract arrives from the SDMX endpoint with CRLF line endings and the recorded SHA-256 is the hash of those bytes, but Git had normalised them to LF on commit. The hash gate therefore passed on the Windows machine this was written on, where checkout restores the CRLFs, and would have stopped every clone on Linux or macOS at the first line of R/load.R. data-raw is now marked -text so Git leaves those bytes alone.

The general point is worth more than the fix: a single machine cannot see a whole class of defect, because the thing that hides the defect is the same thing that makes the analysis run. Only a second platform could find that one.

sessionInfo()
R version 4.6.1 (2026-06-24)
Platform: x86_64-pc-linux-gnu
Running under: Ubuntu 24.04.4 LTS

Matrix products: default
BLAS:   /usr/lib/x86_64-linux-gnu/openblas-pthread/libblas.so.3 
LAPACK: /usr/lib/x86_64-linux-gnu/openblas-pthread/libopenblasp-r0.3.26.so;  LAPACK version 3.12.0

locale:
 [1] LC_CTYPE=C.UTF-8       LC_NUMERIC=C           LC_TIME=C.UTF-8       
 [4] LC_COLLATE=C.UTF-8     LC_MONETARY=C.UTF-8    LC_MESSAGES=C.UTF-8   
 [7] LC_PAPER=C.UTF-8       LC_NAME=C              LC_ADDRESS=C          
[10] LC_TELEPHONE=C         LC_MEASUREMENT=C.UTF-8 LC_IDENTIFICATION=C   

time zone: UTC
tzcode source: system (glibc)

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] knitr_1.51     scales_1.4.0   ggplot2_4.0.3  janitor_2.2.1  validate_1.1.7
[6] tidyr_1.3.2    readr_2.2.0    dplyr_1.2.1   

loaded via a namespace (and not attached):
 [1] bit_4.6.0          gtable_0.3.6       jsonlite_2.0.0     crayon_1.5.3      
 [5] compiler_4.6.1     tidyselect_1.2.1   stringr_1.6.0      parallel_4.6.1    
 [9] snakecase_0.11.1   yaml_2.3.12        fastmap_1.2.0      R6_2.6.1          
[13] labeling_0.4.3     generics_0.1.4     tibble_3.3.1       lubridate_1.9.5   
[17] RColorBrewer_1.1-3 pillar_1.11.1      tzdb_0.5.0         rlang_1.3.0       
[21] stringi_1.8.9      xfun_0.60          S7_0.2.2           bit64_4.8.6       
[25] timechange_0.4.0   cli_3.6.6          withr_3.0.3        magrittr_2.0.5    
[29] digest_0.6.39      grid_4.6.1         vroom_1.7.1        settings_0.2.7    
[33] hms_1.1.4          lifecycle_1.0.5    vctrs_0.7.3        evaluate_1.0.5    
[37] glue_1.8.1         farver_2.1.2       rmarkdown_2.32     purrr_1.2.2       
[41] tools_4.6.1        pkgconfig_2.0.3    htmltools_0.5.9