Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 62 additions & 0 deletions doc/source/utility.rst
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,65 @@ Covariance Estimation
cov_cluster
cov_kernel
group_debias_coefficient


Missing Values
--------------

.. currentmodule:: linearmodels.shared.exceptions

A model drops the observations that have a missing value, such as ``NaN``, in any of
its inputs when it is created. It issues a :class:`MissingValueWarning` if it drops any
observation, and the results use the remaining observations. This is the same in every
model.

The warning is on by default. It can be turned off in three ways.

* Set ``linearmodels.WARN_ON_MISSING`` to ``False``. It applies to every model that is
created afterwards.

.. code-block:: python

import linearmodels

linearmodels.WARN_ON_MISSING = False

* Set the environment variable ``LINEARMODELS_WARN_ON_MISSING`` before importing
linearmodels, for example in the shell that starts Python. The values ``""`` (the
empty string), ``"0"``, ``"false"`` and ``"False"`` turn the warning off. Any other
value, or no variable, leaves it on. The variable is read when linearmodels is
imported, so setting it later has no effect.

.. code-block:: bash

export LINEARMODELS_WARN_ON_MISSING=0

* Use a warnings filter. A filter applies only where it is set, so it can turn off the
warning for part of a program. The warning is issued when the model is created, not
when it is fit.

.. code-block:: python

import warnings

from linearmodels.iv import IV2SLS
from linearmodels.shared.exceptions import MissingValueWarning

with warnings.catch_warnings():
warnings.simplefilter("ignore", MissingValueWarning)
mod = IV2SLS(dependent, exog, endog, instruments)
res = mod.fit()

The action ``"error"`` instead of ``"ignore"`` raises an exception if a model drops
any observation.

.. deprecated:: 7.1

The module attribute ``linearmodels.DROP_MISSING`` and the environment variable
``LINEARMODELS_DROP_MISSING`` have never had an effect, because observations with
missing values are always dropped. Reading ``linearmodels.DROP_MISSING``, and
importing linearmodels when the environment variable is set, issue a
``FutureWarning``. Both will be removed in linearmodels 8.0. Use
``WARN_ON_MISSING`` to turn off the warning.

.. autoclass:: linearmodels.shared.exceptions.MissingValueWarning
65 changes: 62 additions & 3 deletions linearmodels/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,36 @@
- System Estimation using Generalized Method of Moments (GMM)

Designed to work equally well with NumPy, Pandas or xarray data.

Notes
-----
A model drops the observations that have a missing value in any of its inputs when
it is created, and issues a ``MissingValueWarning`` if it drops any. The warning
can be turned off in three ways:

- Set ``linearmodels.WARN_ON_MISSING = False``. It applies to every model that is
created afterwards.
- Set the environment variable ``LINEARMODELS_WARN_ON_MISSING`` before importing
linearmodels. The values ``""``, ``"0"``, ``"false"`` and ``"False"`` turn the
warning off. Any other value leaves it on.
- Use a warnings filter, for example
``warnings.simplefilter("ignore", MissingValueWarning)``, where
``MissingValueWarning`` is imported from ``linearmodels.shared.exceptions``. The
filter applies where it is set, for example inside ``warnings.catch_warnings()``.

``linearmodels.DROP_MISSING`` and the environment variable
``LINEARMODELS_DROP_MISSING`` have never had any effect, because observations with
missing values are always dropped. They are deprecated and will be removed in
linearmodels 8.0. Reading ``DROP_MISSING``, and importing linearmodels when the
environment variable is set, issue a ``FutureWarning``.
"""

from __future__ import annotations

import os
import sys
from typing import TYPE_CHECKING
import warnings

from ._version import version as __version__, version_tuple
from .asset_pricing.model import (
Expand All @@ -65,11 +89,22 @@
OLS = _OLS
_WARN_ON_MISSING = os.environ.get("LINEARMODELS_WARN_ON_MISSING", "1")
WARN_ON_MISSING = False if _WARN_ON_MISSING in ("", "0", "false", "False") else True
_DROP_MISSING = os.environ.get("LINEARMODELS_DROP_MISSING", "1")
DROP_MISSING = False if _DROP_MISSING in ("", "0", "false", "False") else True

# DROP_MISSING and LINEARMODELS_DROP_MISSING have never had an effect. They are
# deprecated and will be removed in 8.0, together with __getattr__ and the tests of
# the deprecation in tests/test_deprecations.py.
_DROP_MISSING = os.environ.get("LINEARMODELS_DROP_MISSING")
if _DROP_MISSING is not None:
warnings.warn(
"The environment variable LINEARMODELS_DROP_MISSING has no effect and will "
"be removed in linearmodels 8.0. Observations with missing values are always "
"dropped. Use LINEARMODELS_WARN_ON_MISSING to turn off the "
"MissingValueWarning.",
FutureWarning,
stacklevel=2,
)

__all__ = [
"DROP_MISSING",
"IV2SLS",
"IV3SLS",
"IVGMM",
Expand All @@ -94,6 +129,30 @@
"version_tuple",
]

if TYPE_CHECKING:
# Type checkers must still see DROP_MISSING, and must not accept any other name
# because of the __getattr__ below
DROP_MISSING: bool
else:

def __getattr__(name: str) -> bool:
# Python calls this function only for names that the module does not define.
# DROP_MISSING is deliberately not defined, so that reading it warns, and it
# is not in __all__, so that import * does not read it. Assigning to
# linearmodels.DROP_MISSING defines it, and then it does not warn.
if name == "DROP_MISSING":
warnings.warn(
"linearmodels.DROP_MISSING has no effect and will be removed in "
"linearmodels 8.0. Observations with missing values are always "
"dropped. Use linearmodels.WARN_ON_MISSING to turn off the "
"MissingValueWarning.",
FutureWarning,
stacklevel=2,
)
# What 7.0 gave: True, unless the environment variable turned it off
return _DROP_MISSING not in ("", "0", "false", "False")
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")


def test(
extra_args: str | list[str] | None = None,
Expand Down
13 changes: 12 additions & 1 deletion linearmodels/shared/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,18 @@


class MissingValueWarning(Warning):
pass
"""
Warning that observations with missing values were dropped.

Notes
-----
A model drops the observations that have a missing value in any of its inputs
when it is created, and issues this warning if it drops any. The warning is on
by default. Set ``linearmodels.WARN_ON_MISSING = False`` or the environment
variable ``LINEARMODELS_WARN_ON_MISSING=0`` to turn it off for every model. To
change it for part of a program, use a warnings filter for this class, with the
action ``"ignore"`` or ``"error"``.
"""


missing_value_warning_msg = """
Expand Down
Loading
Loading