I want to take a CategoricalDistribution, impose a condition, and get a new CategoricalDistribution out. Here’s a notebook with an ugly solution that probably does not generalize well. Can someone come up with something better?
We could make the code a little more general this way:
conditionalDistribution[cd_CategoricalDistribution, outerlevel_] :=
With[{queryElements =
PadRight[{outerlevel}, Length[Information[cd, "Categories"]],
Values]},
CategoricalDistribution[Rest@Information[cd, "Categories"],
Normal@(Query @@ queryElements)[
Information[cd, "ProbabilityTable"]]]
]
But that still seems suboptimal.
If all of the category values are all unique (as in your example), the following might suggest a more general approach:
cd = CategoricalDistribution[{{"A", "B", "C"}, {"\[Alpha]", "\[Beta]"},
{"\[HappySmiley]", "\[SadSmiley]"}},
{{{6, 84}, {8, 48}}, {{63, 91}, {88, 78}}, {{34, 72}, {74, 55}}}];
conditional[dist_, cValues_] := CategoricalDistribution[
Select[Information[dist, "Probabilities"] // Normal, ContainsAll[#[[1]], cValues] &]];
cd1 = conditional[cd, {#}] & /@ Information[cd, "Categories"][[1]];
Information[#, "ProbabilityTable"] & /@ cd1
This also works for conditioning on multiple values (from different variables):
Information[conditional[cd, {"A", "\[Alpha]"}], "ProbabilityTable"]

I came up with an idea that is more general and permits some fairly natural representations of the conditions. I plan on making this into a ResourceFunction. Comments welcome. Here’s a notebook containing the idea.
