Why the curated output looks the way it does: what a variable actually is, what the constraint list means, and why one variable ends up split across several observation files. For definitions of individual terms, see the glossary.
Data Commons has no tables. There are nodes and typed edges between them. Three kinds of node matter when reading a run:
Class · Property · EnumerationThe vocabulary itself. A Class names a kind of thing (Person, FarmInventory); a Property names a relation (count, gender); an Enumeration fixes the legal values of a property. Nothing here holds data — it declares what may be said.
StatisticalVariableA recipe describing what is measured — population, measured property, statistic type, constraints. Still no numbers: one variable node stands behind millions of data points.
StatVarObservationThe facts. Each one binds a variable to an entity, a date and a value. These are the rows in the generated CSVs.
The detail panel shows four core fields. Together they read as a sentence: take the population of things of class FarmInventory, apply the property count, report the raw measured value, in units of Head.
| Field | Role | Value is… | Example |
|---|---|---|---|
populationType | What kind of thing is measured | a Class | FarmInventory |
measuredProperty | Which aspect of it | a Property | count |
statType | How the numbers were reduced | an enum value | measuredValue |
unit | The measurement unit | a UnitOfMeasure node | Head |
Every one of those values is itself a node. That is the whole trick: because count is the same property node everywhere, a Brazilian count and a Japanese count
are comparable without anyone reconciling spreadsheets.
“Is every value a custom enumeration?” — only when the property says so. Each property declares its own range, and that decides the shape of the value:
New classes, properties and enum members can be defined locally — that is what the br/ namespace is for. What cannot be done is putting a value of the wrong shape into
an existing property: the validator rejects it, because the shape is fixed by whoever declared the
property upstream.
Constraints are not a separate mechanism. They are properties on the same variable node; what makes them constraints is their role — they narrow the population.
populationType = FarmInventory ← all farm inventory, everything farmInventoryType = CattleAndCalves ← now only cattle and calves
Each row of a generated CSV becomes one observation node. The variable holds the meaning, so the observation only has to carry the specifics:
variableMeasuredobservationAboutobservationDatevalueunit · measurementMethod · observationPeriodThe obs list shows a type in front of each file — Country, AdministrativeArea2, and so on. That is not a type of the observation:
every observation is a StatVarObservation. It is the type of the entities the file is about, i.e.
the geographic level of its rows.
| Entity type | Example entities | Rows scale with |
|---|---|---|
Country | country/BRA | 1 place |
BrazilianRegion local | Norte, Nordeste, … | 5 places |
AdministrativeArea1 | states | 27 places |
AdministrativeArea2 | municípios | ~5,570 places |
br/IpeaMetropolitanArea local | IPEA metro areas | a few dozen |
So a file with ~142k rows is not a different variable — it is the municipal level, ~5,570
places across ~50 years. Same recipe, finer resolution. The namespace is the tell for which
levels are ours: Country and AdministrativeArea1/2 are standard Data
Commons classes, while BrazilianRegion and br/IpeaMetropolitanArea are defined locally.
“Median income of women aged 25–34 in São Paulo, 2020, in BRL” — first the recipe:
Node: dcid:Median_Income_Person_Female_Years25To34 typeOf: StatisticalVariable populationType: Person ← Class measuredProperty: income ← Property statType: medianValue ← enum value unit: BrazilianReal ← UnitOfMeasure node gender: Female ← constraint, enum value age: [25 34 Years] ← constraint, quantity range
…then one of its many observations:
typeOf: StatVarObservation variableMeasured: Median_Income_Person_Female_Years25To34 observationAbout: br/geoId/3550308 ← entity, typeOf AdministrativeArea2 observationDate: "2020" value: 2400
The separation is the point: the variable says what is measured, the observation says where, when and how much, and the level (AdministrativeArea2) is a fact
about the place node — not about the observation.