Beginner perfumer · 100
Article 100: four fields look 100% filled and are actually 12.3%, 6.2%, 1.7% and 20.9%
· 14 min read
This is the hundredth article in the beginner series, and what it should leave behind is not a reflection but a table. I counted coverage for thirty fields across all 42,225 records — the fullest is CAS at 73.5%, the emptiest is GHS hazard statements at 0.9%. But the ones to watch are the four that look 100%: notes and the three toxicity fields. Every record has text in them, and that text is 'None found' and 'Not determined'. Strip the placeholders and notes is 20.9%, oral toxicity 12.3%, dermal 6.2%, inhalation 1.7%. A field that is 100% full and 88% empty. If this hundred articles leaves one thing, it is this: ask first how many records actually have something in that field.
About a 5 minute read.
This is the hundredth article in the beginner series.
What I want to leave behind is not a retrospective but the table I keep having to recompute.
Coverage across thirty fields
| Field | Non-empty | Coverage | Among the 3,156 with 10+ suppliers |
|---|---|---|---|
| name | 42,225 | 100.0% | 100.0% |
| notes | 42,225 | 100.0% | 100.0% |
| toxicity_oral / dermal / inhalation | 42,224 | 100.0% | 100.0% |
| occurrence | 42,218 | 100.0% | 100.0% |
| cas | 31,035 | 73.5% | 87.0% |
| assay | 27,221 | 64.5% | 66.3% |
| logp | 19,667 | 46.6% | 60.6% |
| cosmetic_uses | 15,459 | 36.6% | 63.4% |
| flash_point | 14,316 | 33.9% | 73.8% |
| bp | 13,009 | 30.8% | 61.7% |
| appearance | 10,270 | 24.3% | 78.8% |
| odor_descriptions | 8,298 | 19.7% | 73.8% |
| potential_uses | 7,807 | 18.5% | 82.9% |
| odor_type | 7,001 | 16.6% | 67.0% |
| flavor | 6,919 | 16.4% | 67.0% |
| odor | 6,913 | 16.4% | 65.7% |
| taste_descriptions | 5,879 | 13.9% | 60.3% |
| specific_gravity | 5,285 | 12.5% | 52.2% |
| refractive_index | 4,609 | 10.9% | 47.7% |
| regulatory | 4,509 | 10.7% | 55.2% |
| fema | 3,617 | 8.6% | 50.4% |
| mp | 3,080 | 7.3% | 28.0% |
| odor_strength | 2,451 | 5.8% | 43.5% |
| structure_class | 2,174 | 5.1% | 27.1% |
| odor_substantivity | 2,035 | 4.8% | 38.8% |
| shelf_life | 1,303 | 3.1% | 24.8% |
| storage | 1,232 | 2.9% | 24.0% |
| ghs_hazard_statements | 369 | 0.9% | 11.0% |
The third column is more useful than the second. The same field is far better filled for materials somebody actually sells — appearance jumps from 24.3% to 78.8%, uses from 18.5% to 82.9%.
But some run the other way. GHS hazard statements reach only 11.0% even among well-supplied records — the emptiest field I have looked at across these hundred articles, and the only one that speaks directly about safety.
And those four 100% figures are false
notes and the three toxicity fields have text in every record. This is the text:
| Field | Placeholder | Records |
|---|---|---|
| notes | "None found" | 33,410 |
| toxicity_oral | "Not determined" | 37,039 |
| toxicity_dermal | "Not determined" | 39,595 |
| toxicity_inhalation | "Not determined" | 41,493 |
Stripping them:
| Field | Apparent | Actual |
|---|---|---|
| notes | 100.0% | 20.9% |
| toxicity_oral | 100.0% | 12.3% |
| toxicity_dermal | 100.0% | 6.2% |
| toxicity_inhalation | 100.0% | 1.7% |
Inhalation toxicity: 731 of 42,225 records carry an actual number.
A field that is 100% full and 98.3% empty.
Write code to count how many materials have toxicity data and WHERE toxicity_oral != '' will answer forty-two thousand. The right answer is five thousand.
The occurrence field is subtler
It is also 100%, and its most common short strings are:
| String | Records |
|---|---|
not found in nature |
14,746 |
| can be natural | 2,932 |
| found in nature | 2,634 |
"Not found in nature" is not a placeholder. It is a claim. And claims can be wrong — I found that this record's version was, in the veramoss article.
A blank tells you nobody filled it in. A wrong claim tells you somebody did, and got it wrong. The second is harder to catch.
What I have had to correct across these hundred
Only a blog that can be wrong can be right. Here is what I have corrected:
- An inference from the FEMA list — I inferred that castoreum absolute was FEMA-listed because the castoreum group is, and the absolute's FEMA field is empty. Lesson: do not infer a record's registration status from its group.
- A regular expression damaged numbers in the palette map — an unbounded numeric replacement turned "97 times lower than DPG" into 107. Lesson: replace by context string.
- How I stated causation for the storage field — I said carboxylic acids "are told to" refrigerate, when all the data shows is which kinds of records came from sources that say so.
- A hypothesis that failed — I guessed conjugated ketones are refrigerated because they photo-oxidise; the measured enrichment was 1.6×, not a signal. I published that as it stood.
- The comparability of substantivity hours — the field reads "N hours at M%" and I read only the first half for a hundred articles; half the "400 hours" in my own map were diluted measurements. Corrected in all three languages.
The fifth was the most expensive lesson: a field's unit may not sit next to the number but in the second half of the same cell.
If only three lines survive
- Ask first whether the cell actually contains something. "Not determined" is also text.
- When you see a unit, find its conditions. Concentration, temperature, pressure, route — those are usually written in the same cell.
- When two records disagree, ask first whether they are the same thing (a FEMA number is not an identifier), then whether they came from the same document (fields are inherited).
These hundred articles have not taught you how to make perfume. They have been doing something else: reading one database until you know when it will lie to you.
What this doesn't establish
- Coverage is counted as "field is non-empty", and I checked placeholders in only five fields. The other twenty-five may hold placeholder patterns I have not found.
- "10+ suppliers" is my own threshold, and changing it changes that whole column.
- Placeholders were found by counting frequent short strings. Longer boilerplate would be missed.
- I cannot distinguish "nobody measured it" from "it was measured and this database does not carry it." "Not determined" covers both.
- Those five corrections are the ones I remember, with no guarantee they are all of them.
- This table is a September 2026 snapshot.