# `causalis.data_contracts.panel_data_did`

## Module Contents

### Classes

`PanelDataDID` | Validated long-format panel contract for staggered-adoption DID.

### Data

`TimeLike` |
`ComparisonGroup` |

### API

causalis.data_contracts.panel_data_did.TimeLike

  None

causalis.data_contracts.panel_data_did.ComparisonGroup

  None

class causalis.data_contracts.panel_data_did.PanelDataDID(/, **data: Any)

  Bases: `pydantic.BaseModel`

  Validated long-format panel contract for staggered-adoption DID.

  Required fields

  df : pandas.DataFrame Long-format panel data. y : str Outcome column name in `df`. unit_col : str Unit identifier column name in `df`. time_col : str Calendar time column name in `df`. Preferred input format is `pandas.Period` values with a regular frequency (for example monthly `Period['M']`). Datetime/string values are accepted only when a regular frequency can be inferred. treated_time : str Binary period-level treatment column in `df` (0/1 or False/True). Treatment is required to be absorbing: once a unit is treated, every later observed row for that unit must remain treated. covariates : sequence of str, optional Optional numeric covariate column names in `df`. The input alias `covariants` is accepted for convenience. cluster_col : str, optional Optional cluster identifier column name in `df`. The input alias `cluster` is accepted for convenience. `unit_col` is valid for unit-level clustering. Estimators that form unit-level influence functions require non-unit cluster columns to be stable within unit; `time_col` is therefore valid for the contract but not for those estimators.

  Notes

  Extra keyword arguments are rejected. The contract derives `treated_units`, `control_units` (never-treated units), `cohorts`, per-unit first treatment dates, and `time_freq` from the input data. `treatment_start` is kept as a compatibility alias for the earliest treatment cohort; staggered estimators should use `cohorts` and `first_treatment_by_unit` instead. This contract is intended for Callaway & Sant’Anna-style staggered difference-in-differences designs. It validates cohort support for at least one estimable `ATT(g,t)` cell using not-yet-treated or never-treated comparison units and exposes a full support table via `att_gt_cells`. The model stores a validated internal dataframe snapshot used by all contract methods; mutating the public `df` attribute after construction does not affect validated contract behavior. Outcome `y` must not contain null/NaN values. Represent missing panel periods by omitting unit-time rows, not by keeping rows with `NaN` outcome. For fiscal quarter/year semantics, pass `time_col` explicitly as `pandas.Period` with the desired fiscal frequency.

  Initialization

  Create a new model by parsing and validating input data from keyword arguments.

  Raises [`ValidationError`][pydantic_core.ValidationError] if the input data cannot be validated to form a valid model.

  `self` is explicitly positional-only to allow `self` as a field name.

  model_config

    ‘ConfigDict(…)’

  df: pandas.DataFrame

    ‘Field(…)’

  y: str

    ‘Field(…)’

  unit_col: str

    ‘Field(…)’

  time_col: str

    ‘Field(…)’

  treated_time: str

    ‘Field(…)’

  covariates: tuple[str, ...]

    ‘Field(…)’

  cluster_col: Optional[str]

    ‘Field(…)’

  property treated_units: Sequence[Hashable]
  property control_units: Sequence[Hashable]
  property never_treated_units: Sequence[Hashable]

    Units that are never treated in the observed panel.

  property first_treatment_by_unit: dict[Hashable, Optional[pandas.Period]]

    Map every unit to its first treatment period, or `None` if never treated.

  property cohort_by_unit: dict[Hashable, pandas.Period]

    Map ever-treated units to their first treatment cohort.

  property cohorts: Sequence[pandas.Period]

    Sorted first-treatment periods among ever-treated units.

  property treatment_start: pandas.Period
  property latest_treatment_start: pandas.Period
  property time_freq: str
  property n_pre_periods: int
  property n_post_periods: int
  property last_post_period: pandas.Period
  property design_type: Literal[canonical_2x2, simultaneous_adoption, staggered_adoption]
  property has_covariates: bool
  property has_cluster: bool
  df_analysis() → pandas.DataFrame
  covariate_frame() → pandas.DataFrame

    Return a copy of the validated covariate design columns.

  cluster_series() → pandas.Series

    Return a copy of the validated cluster identifier column.

  cohort_units(cohort: causalis.data_contracts.panel_data_did.TimeLike) → Sequence[Hashable]

    Return units first treated in the requested cohort.

  not_yet_treated_units(time: causalis.data_contracts.panel_data_did.TimeLike, *, include_never: bool = True) → Sequence[Hashable]

    Return units untreated at `time` because they adopt later or never adopt.

  comparison_units(cohort: causalis.data_contracts.panel_data_did.TimeLike, time: causalis.data_contracts.panel_data_did.TimeLike, *, control_group: causalis.data_contracts.panel_data_did.ComparisonGroup = 'not_yet_or_never') → Sequence[Hashable]

    Return valid comparison units for a Callaway-Sant’Anna `ATT(g,t)` cell.

  df_for_did(*, treated_group_col: str = 'treated_group', post_col: str = 'post', cohort_col: str = 'cohort', event_time_col: str = 'event_time') → pandas.DataFrame

    Return analysis data with derived staggered-DID cohort and event-time columns.

  pre_times(cohort: Optional[causalis.data_contracts.panel_data_did.TimeLike] = None) → Sequence[pandas.Period]
  post_times(cohort: Optional[causalis.data_contracts.panel_data_did.TimeLike] = None) → Sequence[pandas.Period]
  analysis_times() → Sequence[pandas.Period]
  time_to_index() → dict[pandas.Period, int]
  treatment_start_idx(cohort: Optional[causalis.data_contracts.panel_data_did.TimeLike] = None) → int
  att_gt_cells(*, control_group: causalis.data_contracts.panel_data_did.ComparisonGroup = 'not_yet_or_never', anticipation: int = 0, base_period: Literal[universal, varying] = 'universal', include_pre_periods: bool = False, include_unsupported: bool = False) → pandas.DataFrame

    Return Callaway-Sant’Anna `ATT(g,t)` support under an explicit policy.

  cell_counts() → pandas.DataFrame

    Return ever-treated/never-treated row counts by analysis period and own-treatment status.

  __repr__() → str