Skip to content

Conversion

Recast data between resolutions, attach labels, and declare rules.

recast_scale

recast_scale(
    data: Any,
    x: NestedScale,
    source: str | None = None,
    target: str | NestedScale | None = None,
    key: str | None = None,
    values: str | Sequence[str] | None = None,
    rule: str | Mapping[str, str] | None = None,
    weight: str | Mapping[str, str] | None = None,
    na_action: NaAction = "drop",
    parent: str | None = None,
    collect: bool | None = None,
    diagnostics: Diagnostics = "auto",
    missing_sources: MissingSources = "na",
    batch: int | None = None,
    batch_by: str | None = None,
    **kwargs: Any,
) -> Any

Recast values from one resolution to another.

The central conversion verb. Takes a table keyed by unit code at frame source and returns one keyed at target, aggregating (fine to coarse) or disaggregating (coarse to fine) with one rule per value column. Frames that cross-cut work too: the route always goes through the atoms. A crosswalk registered with register_scale_map() short-circuits it.

Columns that are neither the key nor a value column are identifiers (a year, a technology) and are preserved as groups, so panel data recasts in one call. Columns named like the scale's frames are dropped.

Parameters

data The table: pyarrow, pandas, polars, a dict of columns, or a lazy pyarrow Dataset / polars LazyFrame. Returned in the same type. x The scale the codes in data belong to. source Frame of the codes. None infers it: key when that is a frame, else the single frame name among the data's columns. target Target frame of x, or another named scale (its atom layer is the target, matched on shared atom keys). key The code column of data. Defaults to source when that column exists, else the scale's key. values Value columns. Default: every numeric column other than the key and the frame columns; numeric identifiers (year) must be excluded by naming the values. rule One of SCALE_RULES for every value column, or a dict per column. None looks each column up with get_scale_rule(); a column with no rule anywhere is an error. weight Weight column for sum splits and weighted_mean; one name or a dict per column. None uses the registered weight, else the scale's default; with no declared weights every atom weighs 1. na_action Atoms with no code at source or target: "drop" (with a warning), "error", or "keep" (an explicit null row, so totals conserve). parent Rule "share" only: the frame the shares are taken within. Default: target when it differs from source, else the frame above. collect Lazy inputs: True materialises and completes the result; otherwise only the observed target units are returned. diagnostics The checks that scan the data (unknown codes, dropped shares, missing sources): "auto" runs them on eager inputs only; "on"/"off" force. missing_sources "na": a target whose sources are only partly present is null. "ignore": aggregate whatever is there (faster, opt-in). batch, batch_by Process in chunks of at most batch values of the identifier column batch_by (default: the first identifier). Chunking by an identifier leaves the numbers unchanged. **kwargs Passed to scale_map().

Returns

The recast table in the input's type, columns target, identifiers, values. Rule "share" keeps the source key and returns each value as a share of its parent-group total.

recast

recast_scale() -- the central conversion verb (port of R/recast.R).

Aggregation and disaggregation are one operation. Every conversion routes through the atom layer; the route is collapsed into a small crosswalk by scale_map(), so the converter is one join plus one grouped aggregation.

The split factor is fixed for every dimension:

f = w / w_from        when the crosswalk carries weights
f = n_overlap/n_from  otherwise (the equal split)

NA semantics follow R exactly: aggregates do NOT skip nulls (a null member makes its group null), and a target whose sources are only partly present in the data is null (the partial-source poisoning law).

recast

recast(
    x: Any, scale: Any, *args: Any, **kwargs: Any
) -> Any

Recast data x through scale, dispatching on the scale's class.

For a NestedScale the arguments are those of recast_scale(): target is the target frame (or scale) and source the source frame, inferred when omitted. Dimension packages register methods with recast.register(TheirClass).

recast_crosswalk

recast_crosswalk(
    data: Any,
    map: Any,
    source: str,
    target: str,
    key: str | None = None,
    values: str | Sequence[str] | None = None,
    rule: str | Mapping[str, str] | None = None,
    ids: Sequence[str] | None = None,
    by: Sequence[str] = (),
    targets: Sequence[str | None] | None = None,
    missing_sources: MissingSources = "na",
    unit: str = "unit",
    collect: bool | None = None,
) -> Any

Recast values through a given crosswalk.

map has one row per (source, target) pair: the codes in columns source and target, n_from, n_overlap, optionally w (weighted-mean weight; default n_overlap) and w_from (with both, sum splits by w / w_from; otherwise by n_overlap / n_from), and any by columns.

recast_from_atoms

recast_from_atoms(
    data: Any,
    x: NestedScale,
    target: str,
    key: str | None = None,
    values: str | Sequence[str] | None = None,
    rule: str | Mapping[str, str] | None = None,
    weight: str | None = None,
    na_rm: bool = False,
    na_action: NaAction = "drop",
    collect: bool | None = None,
) -> Any

Aggregate atom-keyed data UP into the units of frame target.

weight names a column of the data to weight by (so it may vary by identifier); None uses a weight column if present, else the scale's declared weight. With na_rm=True a null member says nothing rather than making its group null. Unlike recast_scale(), a missing atom simply does not contribute (no partial-source poisoning).

recast_scale

recast_scale(
    data: Any,
    x: NestedScale,
    source: str | None = None,
    target: str | NestedScale | None = None,
    key: str | None = None,
    values: str | Sequence[str] | None = None,
    rule: str | Mapping[str, str] | None = None,
    weight: str | Mapping[str, str] | None = None,
    na_action: NaAction = "drop",
    parent: str | None = None,
    collect: bool | None = None,
    diagnostics: Diagnostics = "auto",
    missing_sources: MissingSources = "na",
    batch: int | None = None,
    batch_by: str | None = None,
    **kwargs: Any,
) -> Any

Recast values from one resolution to another.

The central conversion verb. Takes a table keyed by unit code at frame source and returns one keyed at target, aggregating (fine to coarse) or disaggregating (coarse to fine) with one rule per value column. Frames that cross-cut work too: the route always goes through the atoms. A crosswalk registered with register_scale_map() short-circuits it.

Columns that are neither the key nor a value column are identifiers (a year, a technology) and are preserved as groups, so panel data recasts in one call. Columns named like the scale's frames are dropped.

Parameters

data The table: pyarrow, pandas, polars, a dict of columns, or a lazy pyarrow Dataset / polars LazyFrame. Returned in the same type. x The scale the codes in data belong to. source Frame of the codes. None infers it: key when that is a frame, else the single frame name among the data's columns. target Target frame of x, or another named scale (its atom layer is the target, matched on shared atom keys). key The code column of data. Defaults to source when that column exists, else the scale's key. values Value columns. Default: every numeric column other than the key and the frame columns; numeric identifiers (year) must be excluded by naming the values. rule One of SCALE_RULES for every value column, or a dict per column. None looks each column up with get_scale_rule(); a column with no rule anywhere is an error. weight Weight column for sum splits and weighted_mean; one name or a dict per column. None uses the registered weight, else the scale's default; with no declared weights every atom weighs 1. na_action Atoms with no code at source or target: "drop" (with a warning), "error", or "keep" (an explicit null row, so totals conserve). parent Rule "share" only: the frame the shares are taken within. Default: target when it differs from source, else the frame above. collect Lazy inputs: True materialises and completes the result; otherwise only the observed target units are returned. diagnostics The checks that scan the data (unknown codes, dropped shares, missing sources): "auto" runs them on eager inputs only; "on"/"off" force. missing_sources "na": a target whose sources are only partly present is null. "ignore": aggregate whatever is there (faster, opt-in). batch, batch_by Process in chunks of at most batch values of the identifier column batch_by (default: the first identifier). Chunking by an identifier leaves the numbers unchanged. **kwargs Passed to scale_map().

Returns

The recast table in the input's type, columns target, identifiers, values. Rule "share" keeps the source key and returns each value as a share of its parent-group total.

recast_to_atoms

recast_to_atoms(
    data: Any,
    x: NestedScale,
    source: str | None = None,
    key: str | None = None,
    values: str | Sequence[str] | None = None,
    rule: str | Mapping[str, str] | None = None,
    weight: str | Mapping[str, str] | None = None,
    attach_weight: bool = True,
    collect: bool | None = None,
) -> Any

Project unit-keyed data DOWN to the atom layer (one row per atom).

Extensive columns (rule sum) are split across a unit's atoms by weight so totals conserve; intensive columns are repeated. A weight column is attached so the return trip's weighted_mean reproduces the weighting.

recast_to_atoms

recast_to_atoms(
    data: Any,
    x: NestedScale,
    source: str | None = None,
    key: str | None = None,
    values: str | Sequence[str] | None = None,
    rule: str | Mapping[str, str] | None = None,
    weight: str | Mapping[str, str] | None = None,
    attach_weight: bool = True,
    collect: bool | None = None,
) -> Any

Project unit-keyed data DOWN to the atom layer (one row per atom).

Extensive columns (rule sum) are split across a unit's atoms by weight so totals conserve; intensive columns are repeated. A weight column is attached so the return trip's weighted_mean reproduces the weighting.

recast_from_atoms

recast_from_atoms(
    data: Any,
    x: NestedScale,
    target: str,
    key: str | None = None,
    values: str | Sequence[str] | None = None,
    rule: str | Mapping[str, str] | None = None,
    weight: str | None = None,
    na_rm: bool = False,
    na_action: NaAction = "drop",
    collect: bool | None = None,
) -> Any

Aggregate atom-keyed data UP into the units of frame target.

weight names a column of the data to weight by (so it may vary by identifier); None uses a weight column if present, else the scale's declared weight. With na_rm=True a null member says nothing rather than making its group null. Unlike recast_scale(), a missing atom simply does not contribute (no partial-source poisoning).

recast_crosswalk

recast_crosswalk(
    data: Any,
    map: Any,
    source: str,
    target: str,
    key: str | None = None,
    values: str | Sequence[str] | None = None,
    rule: str | Mapping[str, str] | None = None,
    ids: Sequence[str] | None = None,
    by: Sequence[str] = (),
    targets: Sequence[str | None] | None = None,
    missing_sources: MissingSources = "na",
    unit: str = "unit",
    collect: bool | None = None,
) -> Any

Recast values through a given crosswalk.

map has one row per (source, target) pair: the codes in columns source and target, n_from, n_overlap, optionally w (weighted-mean weight; default n_overlap) and w_from (with both, sum splits by w / w_from; otherwise by n_overlap / n_from), and any by columns.

join_scale

join_scale(
    data: Any,
    x: NestedScale,
    key: str | None = None,
    frame: str | None = None,
    attach: bool | str | Sequence[str] | None = None,
    meta: bool = False,
    weight: str | None = None,
    as_factor: bool = True,
    collect: bool | None = None,
    diagnostics: Diagnostics = "auto",
) -> Any

Attach a label column named after the scale, optionally the codes of coarser frames ("<name>.<frame>") and the unit's share and weight ("<name>.share", "<name>.weight"). Existing columns are never overwritten. With as_factor, memberships are dictionary columns over the frame's full vocabulary.

SCALE_RULES module-attribute

SCALE_RULES = (
    "sum",
    "weighted_mean",
    "mean",
    "copy",
    "sd",
    "share",
    "logshare",
)

register_scale_rule

register_scale_rule(
    param: str,
    rule: str,
    weight: str | None = None,
    scope: str | None = None,
) -> dict

Record the rule (and optionally the weight) for a value column.

get_scale_rule

get_scale_rule(
    param: str, scope: str | None = None
) -> dict | None

The registered entry (rule, weight, scope), or None.

A scoped lookup prefers its own scope and falls back to unscoped.

list_scale_rules

list_scale_rules(scope: str | None = None) -> pa.Table

Registered rules: columns param, rule, weight, scope.

clear_scale_rules

clear_scale_rules(
    name: str | Sequence[str] | None = None,
    scope: str | None = None,
) -> None

Remove rules: the named value columns (within scope), every rule of one scope, or, with neither, everything.