Skip to content

R Python differences

Ivan Svetunkov edited this page Jun 25, 2026 · 3 revisions

R vs Python differences

This page records where the R greybox package and the Python port agree numerically and where they intentionally differ. It complements Roadmap (which tracks what is ported) by documenting how closely the ported functions match.

How parity is checked

The Python repository ships a suite of cross-language comparison tests that run the R package (via rpy2) and the Python port on the same inputs and assert agreement to a numerical tolerance:

Test file Covers
tests/test_r_python_compare.py General ALM fitting, prediction, selection.
tests/test_alm_distributions_compare.py ALM across the supported distributions.
tests/test_diagnostics_compare.py outlier_dummy() vs outlierdummy().
tests/test_pointlik_compare.py Point-wise likelihood.
tests/test_aid_compare.py Demand identification (aid() / aid_cat()) vs R. See AID.

These require rpy2 and the R greybox package installed; they are skipped otherwise.

Verified to agree (to numerical tolerance)

Quantity R Python Notes
Coefficients coef(m) m.coef Across supported distributions.
Fitted values fitted(m) m.fitted
Scale / sigma m$scale m.scale df_residual = n - k.
Outlier dummies outlierdummy() outlier_dummy() Same ids and bounds.
Point likelihood pointLik() point_lik()
STI strengths stick()$strength stick().strength Bit-identical to 6 d.p. on AirPassengers (seasonal 0.1061, trend 0.8613, irregular 0.0326). See EDA.
Smoothers lowess(), supsmu() lowess(), supsmu() Match R to ~1e-15 (the Python smoothers are pybind11 ports of R's C/FORTRAN). See Smoothers.
Demand type aid()$name, $type aid().name, .type Categorical decisions (type, stockout start/end, new/obsolete) match exactly. See AID.

Small last-digit differences can arise from optimiser tolerances (both use gradient-free optimisers but different implementations) and BLAS rounding; they are within the test tolerances. The aid() information-criterion values agree only to about 1e-3 (Python nlopt vs R nloptr), but the resulting categorical classifications are identical.

Intentional convention differences

These are deliberate and will not be "fixed" — they reflect either a language idiom or a correction made during the port.

Topic R Python Why
MPE / MAPE scale fraction fraction The Python port returns these as a fraction (not ×100), matching R. Earlier Python versions returned percentages; aligned as of the port's parity work. See measures.
asymmetry centring centred at C = 0 centred at C = 0 Python's asymmetry in measures() is centred at zero (not at the mean of the errors), matching R.
Distribution count 26 distributions 26 distributions Same families; names match (dnorm, dlnorm, …).

Intentional interface differences

Topic R Python
Model fitting formula interface: alm(y ~ x, data, ...) scikit-learn style: ALM(...).fit(X, y). Use formula() to build X/y.
Naming case camelCase functions (alm, xregExpander) snake_case functions / PascalCase classes (ALM, xreg_expander). Full map on Home.
Result access R lists with $ (m$coefficients) objects with attributes (m.coef)
stick seasonal lags lags defaults to frequency(y) lags is required (Python arrays carry no frequency); raises ValueError if omitted. See EDA.
Time series input ts objects carry frequency/start plain numpy arrays / pandas Series; periodicity is passed explicitly.

Not in Python yet

Functions that are R-only (so there is nothing to compare) are listed on Roadmap.

References

See Resources for the full reference list.

Clone this wiki locally