axiom

Making a model travel · step 3 of 6

Four things the graph can say

What happens when the populations differ somewhere worse?

The same question against four different beliefs about what differs. Only one of them is the happy case, and one of the other three is better news than it looks: if the target population can identify the effect from its own data, the source study is not needed at all.

Note the last one. axiom does not say 'not transportable' — it says unsupported, and names the gap: the complete sID recursion is not implemented, so a transfer may exist that these three sufficient conditions cannot see. A tool that answered 'no' there would be lying about the strength of its own evidence.

step 3
edges = ("filters -> illness, age -> illness, age -> filters,"
         " sanitation -> illness, sanitation -> filters")
beliefs = {
    "only the age mix differs":
        dict(selection=["age"]),
    "illness itself behaves differently there":
        dict(selection=["illness"]),
    "sanitation differs, and nobody measured it":
        dict(unmeasured=["sanitation"], selection=["sanitation"]),
    "illness differs and age was never measured":
        dict(unmeasured=["age"], selection=["illness"]),
}
for belief, kw in beliefs.items():
    g = CausalGraph.from_edges(edges, name="belief", **kw)
    v = transport_verdict(g, "filters", "illness")
    print(f"{belief:44s} {v.status:12s} {v.verdict.route or '-'}")
print()
print("the second one is not a failure -- 'trivial' means the target")
print("identifies the effect from its own data and does not need the trial.")
print("the fourth names its own gap rather than claiming a negative:")
g = CausalGraph.from_edges(
    edges, unmeasured=["age"], selection=["illness"], name="worst")
print("  ", transport_verdict(g, "filters", "illness").missing)
what it printed
only the age mix differs                     identified   s_admissible_adjustment
illness itself behaves differently there     identified   trivial
sanitation differs, and nobody measured it   downgraded   s_admissible_adjustment_unmeasured
illness differs and age was never measured   unsupported  -

the second one is not a failure -- 'trivial' means the target
identifies the effect from its own data and does not need the trial.
the fourth names its own gap rather than claiming a negative:
   ('sid_recursion',)

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.