Bringing your own problem · step 2 of 6
Say what the columns mean
Why does a column need a dimension and a unit?
A Treatment and an Outcome are not labels. They carry a dimension and a unit, and those travel with every number derived from them — into the estimand, into the transfer ledger, onto the report.
This is what stops dollars being added to visits four steps later, in a function nobody is reading at the time. D.currency and D.outcome are different dimensions, and axiom refuses the arithmetic that would mix them rather than returning a number with no meaning.
step 2
from axiom.core import D, Outcome, Treatment
from axiom.data import Panel, RoleMap
leaflets = Treatment(
name="leaflets",
dimension=D.currency,
unit="USD/store-week",
description="leaflet spend delivered to the store's catchment",
)
footfall = Outcome(
name="footfall",
dimension=D.outcome,
unit="visits/week",
description="counted entries through the door",
aggregation="mean",
)
roles = RoleMap(
unit="store",
time="week",
outcome=("footfall", footfall),
treatments={"leaflets": leaflets},
)
panel = Panel(frame, roles)
print(f"unit column : {roles.unit}")
print(f"time column : {roles.time}")
print(f"outcome column : {roles.outcome[0]} [{footfall.dimension}]")
print(f"treatment columns: {list(roles.treatments)} "
f"[{leaflets.dimension}]")
print()
print(f"the two dimensions are different objects: "
f"{D.currency != D.outcome}")
what it printed
unit column : store time column : week outcome column : footfall [Y] treatment columns: ['leaflets'] [$] the two dimensions are different objects: True
Every line above was captured by running this code at build time. The steps share one namespace, so the code on this page is the code you would type after the steps before it.