About This Site
Research Methods and Data Standards
How the datasets are built, what counts as a finding, when a number gets withheld, and what we do with the data you submit. The companion to how we research and fact check, which covers the guides.
The short answer
- Two kinds of output live here and they are labeled differently: compiled data derived from our own sourced pages, and observed data submitted from the field. Never mixed, never presented as the same thing.
- Datasets are built by published scripts from published pages, so anyone can regenerate them and check us.
- Aggregates are withheld below 5 observations per row and 20 per section. Thin data is shown as thin, not rounded into a finding.
- Protocol pages carry no results until runs exist. A protocol is a plan, and we do not dress plans up as outcomes.
- No account, no email, no IP address stored. Rate limiting uses a salted one-way hash.
Two kinds of data#
Everything in this section is one of two things, and confusing them is the main way a research page becomes dishonest.
| Compiled | Observed | |
|---|---|---|
| What it is | Structured extraction from our own sourced guides | Field observations submitted by readers |
| Example | Trait matrix | Feeder Log |
| Originality | The structure and the analyses, not the underlying facts | The observations themselves |
| Verification | Regenerate with the published script | Sample size published on every table |
| Fails when | Our profiles are wrong or phrase something unusually | Contributors misidentify birds or submit selectively |
Pages built on compiled data say so in their method box and in a limits section. We are not going to describe a table extracted from our own writing as if we went outside and counted birds.
How the trait matrix is extracted#
Each species profile carries an "At a glance" definition list with a fixed set of fields. The builder reads those fields for all 78 profiles and does four things.
- Parses measurements. Every measurement on this site is written in both units, as
8.3 to 9.1 in (21 to 23 cm). The builder takes the metric figure from inside the parentheses and stores min, max and midpoint. Imperial is presentation, metric is the stored value. - Tags foods and feeder types. The free-text fields are matched against the pattern lists below. A species gets a tag when any pattern for that tag matches, so a species can carry several.
- Detects non-feeder species. Profiles whose feeder field is an explicit negative
are flagged
uses_feeders=falseand excluded from feeder analyses, rather than being recorded as compatible with nothing. Currently 5 of 78 species. - Classifies residency from the range and at-feeders text into resident, migratory, winter visitor or mixed.
No step involves a judgment call at runtime, which is the point: the same input always gives the same output, and any disagreement is a disagreement about a rule you can read.
Food tagging rules#
Patterns are matched case-insensitively against the "Favorite foods" text.
| Tag | Matched when the food text contains |
|---|---|
black_oil_sunflower | black oil sunflower, \bsunflower seed, ^sunflower$ |
sunflower_hearts | sunflower hearts, sunflower chips, hulled sunflower |
striped_sunflower | striped sunflower |
safflower | safflower |
nyjer | nyjer, thistle |
white_millet | millet |
cracked_corn | cracked corn, \bcorn\b |
peanuts | peanut |
suet | suet |
mealworms | mealworm |
nectar | nectar, sugar water |
fruit | fruit, berr, orange, grape jelly, raisin, apple |
insects | insect, spider, caterpillar, beetle, larva, invertebrate, ant\b, wasp |
acorns_nuts | acorn, \bnuts?\b, walnut, pecan, beech |
Feeder tagging rules#
Matched against the "Best feeder" text.
| Tag | Matched when the feeder text contains |
|---|---|
tube | \btube\b |
hopper | hopper |
platform_tray | platform, \btray\b, open feeder |
ground | ground, scattered on the ground, beneath the feeder |
suet_cage | suet cage, suet feeder, tail-prop |
nyjer_finch | nyjer tube, finch feeder, mesh finch, thistle sock, sock feeder |
peanut_feeder | peanut feeder, peanut cage, wire mesh |
nectar_feeder | nectar feeder, hummingbird feeder, oriole feeder, saucer, basin |
dish | \bdish\b, cup\b, jelly feeder |
These rules are deliberately literal, and that has a cost worth naming. A profile that discusses a feeder type only in its body text and not in the summary block will not get the tag. That makes the matrix conservative: it under-reports compatibility rather than inventing it, which is the safer direction for an analysis that draws conclusions about coverage.
Publication thresholds#
Live aggregates are governed by two numbers.
- 5 observations minimum per row. A food, feeder type or region with fewer than that is not shown as its own row.
- 20 observations minimum per section. Below that the whole table is replaced with a plain statement of how many observations exist and how many are needed.
These are not high bars, and they are not meant to be. They exist to stop the specific failure of a research page confidently reporting that "67% of observations" showed something when the denominator was three.
What we let ourselves claim#
Language is tiered the same way our source hierarchy tiers it.
| Evidence | How it may be written |
|---|---|
| An analysis of the trait matrix | "Our matrix records", "in this dataset", always with n and always linked to the data |
| Feeder Log aggregate above threshold | "Across n observations submitted so far", with the count stated inline |
| Feeder Log aggregate below threshold | Not written as a result at all |
| A protocol with no runs yet | Described as a procedure. Never "we found", never "testing shows" |
| A mechanism we are inferring | Marked as reasoning: "the likely explanation", "this is consistent with" |
The rule underneath all of it: a reader should never have to guess whether a sentence reports a measurement, a compilation or an inference.
Bird welfare comes before data#
Every protocol on this site is constrained by this and it is not negotiable.
- No design withholds food, restricts access or creates competition as an experimental variable. Preference trials keep every feeder full.
- No trapping, no handling, no marking, no banding. None of it is needed for anything we publish and all of it requires permits we do not hold.
- Nothing goes on a feeder, a pole or into food that could harm a bird. No greased poles, no sticky deterrents, no additives.
- Any protocol that starts producing a welfare problem gets stopped, not finished. A run abandoned because a feeder went moldy or a hawk moved in is a good outcome, and you should submit it as one.
- Hygiene rules from our cleaning guide apply during a run exactly as they do the rest of the year.
What we store about you#
Feeder Log submissions store the fields on the form and nothing else. No account, no email address, no IP address, no cookie, no analytics identifier tied to a submission. The name field is optional and blank means anonymous.
Rate limiting needs to recognize a repeat submitter without identifying them, so we store a truncated SHA-256 hash of a fixed salt combined with the request IP and user agent. It cannot be reversed into an address, it is not shared, and it is not in the public export. Full detail is in the privacy policy.
Correcting the data#
The corrections policy covers research pages exactly as it covers guides. Three things are worth correcting and we want all of them: a wrong value in the trait matrix, which usually means a wrong value in the underlying profile; an extraction rule that mis-tags a species; and an analysis whose conclusion does not follow from its data.
The third is the most valuable and the least likely to be reported. If a finding here is overreaching, say so through the contact page. Findings pages carry the same correction notes as any other page when they change.