code: def chi2_mcnemar(data, x, y, correction=True):
      """
      Performs the exact and approximated versions of McNemar's test.
  
      Parameters
      ----------
      data : :py:class:`pandas.DataFrame`
          The dataframe containing the ocurrences for the test. Each row must
          represent either a subject or a pair of subjects.
      x, y : string
          The variables names for the McNemar's test. Must be names of columns
          in ``data``.
  
          If each row of ``data`` represents a subject, then ``x`` and ``y`` must
          be columns containing dichotomous measurements in two different
          contexts. For instance: the presence of pain before and after a certain
          treatment.
  
          If each row of ``data`` represents a pair of subjects, then ``x`` and
          ``y`` must be columns containing dichotomous measurements for each of
          the subjects. For instance: a positive response to a certain drug in
          the control group and in the test group, supposing that each pair
          contains a subject in each group.
  
          The 2x2 crosstab is created using the
          :py:func:`pingouin.dichotomous_crosstab` function.
  
          .. warning:: Missing values are not allowed.
  
      correction : bool
          Whether to apply the correction for continuity (Edwards, A. 1948).
  
      Returns
      -------
      observed : :py:class:`pandas.DataFrame`
          The observed contingency table of frequencies.
      stats : :py:class:`pandas.DataFrame`
          The test summary:
  
          * ``'chi2'``: The test statistic
          * ``'dof'``: The degree of freedom
          * ``'p-approx'``: The approximated p-value
          * ``'p-exact'``: The exact p-value
  
      Notes
      -----
      The McNemar's test is compatible with dichotomous paired data, generally
      used to assert the effectiveness of a certain procedure, such as a
      treatment or the use of a drug. "Dichotomous" means that the values of the
      measurements are binary. "Paired data" means that each measurement is done
      twice, either on the same subject in two different moments or in two
      similar (paired) subjects from different groups (e.g.: control/test). In
      order to better understand the idea behind McNemar's test, let's illustrate
      it with an example.
  
      Suppose that we wanted to compare the effectiveness of two different
      treatments (X and Y) for athlete's foot on a certain group of `n` people.
      To achieve this, we measured their responses to such treatments on each
      foot. The observed data summary was:
  
      * Number of people with good responses to X and Y: `a`
      * Number of people with good response to X and bad response to Y: `b`
      * Number of people with bad response to X and good response to Y: `c`
      * Number of people with bad responses to X and Y: `d`
  
      Now consider the two groups:
  
      1. The group of people who had good response to X (`a` + `b` subjects)
      2. The group of people who had good response to Y (`a` + `c` subjects)
  
      If the treatments have the same effectiveness, we should expect the
      probabilities of having good responses to be the same, regardless of the
      treatment. Mathematically, such statement can be translated into the
      following equation:
  
      .. math::
  
          \\frac{a+b}{n} = \\frac{a+c}{n} \\Rightarrow b = c
  
      Thus, this test should indicate higher statistical significances for higher
      distances between `b` and `c` (McNemar, Q. 1947):
  
      .. math::
  
          \\chi^2 = \\frac{(b - c)^2}{b + c}
  
      References
      ----------
      * Edwards, A. L. (1948). Note on the "correction for continuity" in
        testing the significance of the difference between correlated
        proportions. Psychometrika, 13(3), 185-187.
  
      * McNemar, Q. (1947). Note on the sampling error of the difference
        between correlated proportions or percentages. Psychometrika, 12(2),
        153-157.
  
      Examples
      --------
      >>> import pingouin as pg
      >>> data = pg.read_dataset('chi2_mcnemar')
      >>> observed, stats = pg.chi2_mcnemar(data, 'treatment_X', 'treatment_Y')
      >>> observed
      treatment_Y   0   1
      treatment_X
      0            20  40
      1             8  12
  
      In this case, `c` (40) seems to be a significantly greater than `b` (8).
      The McNemar test should be sensitive to this.
  
      >>> stats
                  chi2  dof  p-approx   p-exact
      mcnemar  20.020833    1  0.000008  0.000003
      """
      # Python code initially inspired by statsmodel's mcnemar
      assert isinstance(
          data, pd.DataFrame
      ), "data must be a pandas DataFrame."
      assert all(
          isinstance(column, (str, int)) for column in (x, y)
      ), "column names must be string or int."
      assert all(
          column in data.columns for column in (x, y)
      ), "columns are not in dataframe."
  
      for column in (x, y):
          if data[column].isna().any():
              raise ValueError("Null values are not allowed.")
  
      observed = dichotomous_crosstab(data, x, y)
      # Careful, the order of b and c is inverted compared to wikipedia
      # because the colums / rows of the crosstab is [0, 1] and not [1, 0].
      c, b = observed.at[0, 1], observed.at[1, 0]
      n_discordants = b + c
  
      if (b, c) == (0, 0):
          raise ValueError(
              "McNemar's test does not work if the secondary "
              + "diagonal of the observed data summary does not "
              + "have values different from 0."
          )
  
      chi2 = (abs(b - c) - int(correction)) ** 2 / n_discordants
      pexact = min(1, 2 * binom.cdf(min(b, c), n_discordants, 0.5))
      stats = {
          "chi2": chi2,
          "dof": 1,
          "p-approx": sp_chi2.sf(chi2, 1),
          "p-exact": pexact,
          # 'p-mid': pexact - binom.pmf(b, n_discordants, 0.5)
      }
  
      stats = pd.DataFrame(stats, index=["mcnemar"])
  
      return observed, _postprocess_dataframe(stats)
  
file_path: pingouin/pingouin/contingency.py
imports: import warnings
  import numpy
  import pandas
  from scipy.stats.contingency import expected_freq
  from scipy.stats import power_divergence, binom, chi2
  from pingouin import power_chi2, _postprocess_dataframe
label_desc: Use image node_id 2 for calling a global function with example usage: chi2_mcnemar(data, x, y, correction) and returns: observed,  _postprocess_dataframe