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.