Source code for celldetective.utils.stats

from typing import Optional, Union, List, Any

import pandas as pd
from cliffs_delta import cliffs_delta
from scipy.stats import ks_2samp


[docs] def test_2samp_generic( data: pd.DataFrame, feature: Optional[str] = None, groupby_cols: Optional[Union[str, List[str]]] = None, method: str = "ks_2samp", *args: Any, **kwargs: Any, ) -> pd.DataFrame: """ Performs pairwise statistical tests between groups of data, comparing a specified feature using a chosen method. The function applies two-sample statistical tests, such as the Kolmogorov-Smirnov (KS) test or Cliff's Delta, to compare distributions of a given feature across groups defined by `groupby_cols`. It returns the test results in a pivot table format with each group's pairwise comparison. Parameters ---------- data : pandas.DataFrame The input dataset containing the feature to be tested. feature : str The name of the column representing the feature to compare between groups. groupby_cols : list or str The column(s) used to group the data. These columns define the groups that will be compared pairwise. method : str, optional, default="ks_2samp" The statistical test to use. Options: - "ks_2samp": Two-sample Kolmogorov-Smirnov test (default). - "cliffs_delta": Cliff's Delta for effect size between two distributions. *args, **kwargs : Additional arguments and keyword arguments for the selected test method. Returns ------- pivot : pandas.DataFrame A pivot table containing the pairwise test results (p-values or effect sizes). The rows and columns represent the unique groups defined by `groupby_cols`, and the values represent the test result (e.g., p-values or effect sizes) between each group. Notes ----- - The function compares all unique pairwise combinations of the groups based on `groupby_cols`. - For the "ks_2samp" method, the test compares the distributions using the Kolmogorov-Smirnov test. - For the "cliffs_delta" method, the function calculates the effect size between two distributions. - The results are returned in a symmetric pivot table where each cell represents the test result for the corresponding group pair. """ assert groupby_cols is not None, "Please set a valid groupby_cols..." assert feature is not None, "Please set a feature to test..." results = [] for lbl1, group1 in data.dropna(subset=feature).groupby(groupby_cols): for lbl2, group2 in data.dropna(subset=feature).groupby(groupby_cols): dist1 = group1[feature].values dist2 = group2[feature].values if method == "ks_2samp": test = ks_2samp( list(dist1), list(dist2), alternative="less", mode="auto", *args, **kwargs, ) val = test.pvalue elif method == "cliffs_delta": test = cliffs_delta(list(dist1), list(dist2), *args, **kwargs) val = test[0] results.append({"cdt1": lbl1, "cdt2": lbl2, "value": val}) results = pd.DataFrame(results) results["cdt1"] = results["cdt1"].astype(str) results["cdt2"] = results["cdt2"].astype(str) pivot = results.pivot(index="cdt1", columns="cdt2", values="value") pivot.reset_index(inplace=True) pivot.columns.name = None pivot.set_index("cdt1", drop=True, inplace=True) pivot.index.name = None return pivot