cleverly.longitudinal.each_node#

cleverly.longitudinal.each_node(rule: Callable[[Any, int], Any], n_times: int) → tuple[NodeRule, ...][source]#

Write one rule for every node, each reading its own node’s columns by name.

Node t calls rule(frame, t). On a container built from a long panel, the covariate eng measured at node t is the column f"eng@{t}". A rule that names it reads exactly that node’s value. When that column is absent, for example because it was constant at the node and screened out, the fit raises rather than read an earlier node.

Parameters:
rulecallable()

rule(frame, t) returns one arm per row for a rule node, or one probability per level for a Stochastic density.

n_timesint

The number of nodes.

Returns:
tuple of NodeRule

One callable per node, in node order.

Raises:
DataError

If n_times is not a positive integer.

See also

cleverly.longitudinal.DynamicRegimen

The plan that holds the rules.

cleverly.longitudinal.LongitudinalData.from_long_panel

The names the rules read.

Examples

>>> import numpy as np
>>> import pandas as pd
>>> from cleverly.longitudinal import each_node
>>> rules = each_node(lambda h, t: np.where(h[f"eng@{t}"] > 0, "offer", "none"), 2)
>>> history = pd.DataFrame({"W": [0.0, 1.0], "eng@1": [0.5, -1.0], "eng@2": [-2.0, 3.0]})
>>> rules[0](history).tolist(), rules[1](history).tolist()
(['offer', 'none'], ['none', 'offer'])