Skip to contents

Every cut-off in Tables 3 and 4a-4g of the Intake methods paper, in long format: one row per metric, indicator, demographic group and table row.

Usage

eiod_cutoffs

Format

A data frame with 616 rows and 15 columns:

metric

`"abs"` for Table 3, `"rel"` for Tables 4a-4g

table

Source table: `"3"`, `"4a"` ... `"4g"`

indicator

Short indicator name used by the `eiod_*` functions

indicator_label

Human-readable indicator name

unit

Unit **this table is printed in**, per capita per day. The same for both tables for six indicators; for eutrophication, kg for Table 3 and g for Table 4f

demogroup

Demographic group, 1-8

demogroup_label

Group name, e.g. "Male 10+ yr"

sex

Factor, `"male"` or `"female"`

age_min, age_max

Age bounds in years; 999 means no upper bound

row_order

Position in the source table

percentile

10-90 for relative rows 1-9; `NA` for absolute rows and for row 10, which repeats P90 as a lower bound

value

**The cut-off the metric functions compare against.** Nothing is rescaled: for 608 rows this is exactly what the paper prints, and for the other eight it is exactly what Intake supplied

value_published_str

The same value as a character string, exactly as received. Shipped so the figure can be compared character for character, not as a rendering of a double

value_source

`"published"` for the 608 rows transcribed from the paper; `"intake correction 2026-10"` for the eight Table 3 eutrophication thresholds Intake corrected. **Those eight do not match the currently published PDF** - see the section above

Source

Intake-EIOD-Methods-Paper-Jan2026-Final.pdf, Tables 3 and 4a-4g (pages 16-19), available at <https://www.intake.org/sites/default/files/2026-01/Intake-EIOD-Methods-Paper-Jan2026-Final.pdf>. Transcribed programmatically; see `data-raw/build_data.R`. The same source file drives a companion Stata implementation.

Details

Tables 5a and 5b are deliberately **not** stored here. They are composites that reuse values already present - the HESD criterion is `metric == "abs" & indicator == "biodiv"`, and the HDLEI criterion is `metric == "rel" & indicator == "biodiv" & percentile == 30`. A second copy could drift from the first.

Nothing here is rescaled

**`value` is the cut-off exactly as this package received it, for all 616 rows**, and `value_published_str` is the same number as literal text. The package applies no conversion to a cut-off and none to your data.

For 608 rows "as received" means "as printed in the methods paper", and you can check them against the PDF character for character. The remaining eight are described in the next section.

Eight rows differ from the published PDF, on Intake's instruction

The **Table 3 eutrophication thresholds** in `eiod_cutoffs` are **not** the numbers the currently published paper prints. They are corrections supplied by Intake in October 2026, and the `value_source` column marks them:

“`r subset(eiod_cutoffs, value_source != "published", c(demogroup_label, unit, value, value_source)) “`

**What was wrong.** The paper prints those eight cells in **kilograms** PO4(3-)eq while Table 4f, and the EIOF food databases, use **grams**. Intake confirmed by email that both tables are intended to be in grams, and supplied the corrected Table 3 values.

**What changed, and what did not.** The corrected values are the printed ones multiplied by 1000, carried to full precision - the quantity is identical, only the unit it is expressed in has changed. Dividing any corrected value by 1000 reproduces the printed figure to the ten decimals the PDF gives, and `data-raw/build_data.R` asserts exactly that. **No classification moves**: tested on 400,000 simulated gram-scale values, old and new behaviour agreed everywhere except within about one unit in the last place of a cut-off, where the new path is the more exact of the two because it no longer divides before comparing.

**Consequence for you: supply eutrophication in grams**, which is what the EIOF databases give you (`Eutr. (g PO43-e/kg)` x kg food = g). Every indicator now uses one unit across both tables, and nothing is converted anywhere. Between July and October 2026 this package divided eutrophication values by 1000 on your behalf; that step is gone.

See `vignette("eutrophication")` for the full history, including the evidence that led to the question being raised.

Checking a value against the printed table

Two columns carry the same number in two forms, so that a reader can check the package without having to trust any numeric rendering:

`value_published_str`the literal characters from the paper, never through a numeric type
`value`the nearest IEEE 754 double to that text - and what the metric functions compare against

`data-raw/build_data.R` asserts that `as.numeric(value_published_str) == value` for all 616 rows, and that each parsed value still prints back to exactly its published digits.

A `double` cannot hold most decimal fractions exactly - that is true of every statistical package, not of this one. What is guaranteed here is that the stored double is the nearest double to the published decimal, that it round-trips back to that decimal, and that the decimal itself is in the file as text. **If you need an exact decimal comparison, compare against `value_published_str`.**

Note that R's default `options(digits = 7)` will not show you a published value in full: 15 of the 616 need 14 significant digits. [eiod_lookup_cutoff()] prints at full precision for this reason.

Examples

data(eiod_cutoffs)
str(eiod_cutoffs)
#> 'data.frame':	616 obs. of  15 variables:
#>  $ metric             : chr  "abs" "abs" "abs" "abs" ...
#>  $ table              : chr  "3" "3" "3" "3" ...
#>  $ indicator          : chr  "biodiv" "biodiv" "biodiv" "biodiv" ...
#>  $ indicator_label    : chr  "Biodiversity loss" "Biodiversity loss" "Biodiversity loss" "Biodiversity loss" ...
#>  $ unit               : chr  "PDF*year" "PDF*year" "PDF*year" "PDF*year" ...
#>  $ demogroup          : int  1 2 3 4 5 6 7 8 1 2 ...
#>  $ demogroup_label    : chr  "Male 0-1.9 yr" "Male 2-4.9 yr" "Male 5-9.9 yr" "Male 10+ yr" ...
#>  $ sex                : Factor w/ 2 levels "male","female": 1 1 1 1 2 2 2 2 1 1 ...
#>  $ age_min            : num  0 2 5 10 0 2 5 10 0 2 ...
#>  $ age_max            : num  1.9 4.9 9.9 999 1.9 4.9 9.9 999 1.9 4.9 ...
#>  $ row_order          : int  7 7 7 7 7 7 7 7 5 5 ...
#>  $ percentile         : int  NA NA NA NA NA NA NA NA NA NA ...
#>  $ value              : num  3.69e-13 5.72e-13 7.88e-13 1.28e-12 3.57e-13 ...
#>  $ value_published_str: chr  "3.6896027444E-13" "5.7244838747E-13" "7.8836516181E-13" "1.2844358718E-12" ...
#>  $ value_source       : chr  "published" "published" "published" "published" ...

# the HESD biodiversity criterion
subset(eiod_cutoffs, metric == "abs" & indicator == "biodiv",
       c(demogroup_label, value))
#>   demogroup_label        value
#> 1   Male 0-1.9 yr 3.689603e-13
#> 2   Male 2-4.9 yr 5.724484e-13
#> 3   Male 5-9.9 yr 7.883652e-13
#> 4     Male 10+ yr 1.284436e-12
#> 5 Female 0-1.9 yr 3.574921e-13
#> 6 Female 2-4.9 yr 5.301871e-13
#> 7 Female 5-9.9 yr 7.238206e-13
#> 8   Female 10+ yr 1.033173e-12