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
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,15 @@
"\n",
"An omnibus analysis across groups\n",
"is combined with posthoc analysis between each set of the separate groups.\n",
"The omnibus test's adjusted p-value and rejection flag are in `padj` and\n",
"`rejected`; pairwise posthoc results use `posthoc pvalue adj` and\n",
"`posthoc rejected`.\n",
"`Method` records the selected omnibus test (`One-way anova` here); use\n",
"`run_ancova` when covariates should be included in the omnibus model.\n",
"\n",
"The function is the same as for the two groups case. The `group1` and\n",
"`group2` columns give the posthoc comparison.\n"
"`group2` columns give the posthoc comparison, also available as\n",
"`posthoc comparison` in the form `group1~~group2`.\n"
]
},
{
Expand Down Expand Up @@ -85,7 +91,6 @@
"id": "2d8f94e4",
"metadata": {},
"source": [
"# ANOVA analysis for two groups\n",
"Use combined dataset for ANOVA analysis."
]
},
Expand Down Expand Up @@ -176,8 +181,18 @@
"lines_to_next_cell": 2
},
"source": [
"## With four groups\n",
"Acore make each combinatorial comparison between groups in the group column."
"# Run ANOVA with four groups\n",
"Acore runs an omnibus test asking if any of the groups are significantly different, so\n",
"if a feature as any effect (F-test between a regression with group dummies and without\n",
"any) and also runs pairwise (posthoc) tests to identify which groups are different and\n",
"in which direction. The omnibus test's adjusted p-value and rejection flag are in\n",
"`padj` and `rejected`; pairwise posthoc results use `posthoc pvalue adj` and `posthoc\n",
"rejected`. `Method` records the selected omnibus test (`One-way anova` here); use\n",
"`run_ancova` when covariates should be included in the omnibus model.\n",
"\n",
"The function is the same as for the two groups case. The `group1` and `group2` columns\n",
"give the posthoc comparison, also available as `posthoc comparison` in the form\n",
"`group1~~group2`."
]
},
{
Expand Down Expand Up @@ -206,7 +221,8 @@
"id": "59527f87",
"metadata": {},
"source": [
"### pairwise t-test results:"
"## pairwise (posthoc) t-test results\n",
"posthoc t-test results to identify which groups are different and in which direction."
]
},
{
Expand All @@ -223,6 +239,7 @@
"cols_pairwise_ttest = [\n",
" # \"group1\",\n",
" # \"group2\",\n",
" \"posthoc comparison\",\n",
" \"mean(group1)\",\n",
" \"std(group1)\",\n",
" \"mean(group2)\",\n",
Expand All @@ -234,6 +251,7 @@
" \"posthoc tail\",\n",
" \"posthoc pvalue\",\n",
" \"posthoc pvalue adj\",\n",
" \"posthoc rejected\",\n",
" \"posthoc BF10\",\n",
" \"posthoc effsize\",\n",
" # \"identifier\",\n",
Expand Down Expand Up @@ -293,9 +311,11 @@
"lines_to_next_cell": 2
},
"source": [
"## Volcano plot of ANOVA results\n",
"- volcano plot of ANOVA (omnibus test) results\n",
"- more than one group present in the example."
"## Posthoc volcano plot: WRP versus WT\n",
"Select one pairwise comparison so each identifier has one point.\n",
"The x-axis shows its `log2FC`, the y-axis its posthoc p-value, and\n",
"the color its posthoc FDR significance decision (`posthoc rejected`).\n",
"Change `comparison` to another value from the `posthoc comparison` column."
]
},
{
Expand All @@ -309,17 +329,20 @@
},
"outputs": [],
"source": [
"comparison = \"WRP~~WT\"\n",
"pairwise_results = anova.loc[anova[\"posthoc comparison\"] == comparison].reset_index()\n",
"\n",
"scatter_plot_adv = vuecore.plots.basic.scatter.create_scatter_plot(\n",
" data=anova.reset_index(),\n",
" data=pairwise_results,\n",
" x=\"log2FC\",\n",
" y=\"-log10 pvalue\",\n",
" color=\"rejected\",\n",
" title=\"Simple Volcano Plot\",\n",
" subtitle=\"Visualizing ANOVA results\",\n",
" y=\"-log10 posthoc pvalue\",\n",
" color=\"posthoc rejected\",\n",
" title=\"Posthoc Volcano Plot\",\n",
" subtitle=comparison.replace(\"~~\", \" versus \"),\n",
" labels={\n",
" \"log2FC\": \"Log2 Fold Change\",\n",
" \"-log10 pvalue\": \"-log10(p-value)\",\n",
" \"rejected\": \"FDR corrected Significant\",\n",
" \"log2FC\": f\"log2 fold change ({comparison.replace('~~', ' / ')})\",\n",
" \"-log10 posthoc pvalue\": \"-log10(posthoc p-value)\",\n",
" \"posthoc rejected\": \"Posthoc FDR corrected significant\",\n",
" \"identifier\": \"Protein Identifier\",\n",
" },\n",
" hover_data=[\"identifier\", \"group1\", \"group2\"],\n",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,15 @@
#
# An omnibus analysis across groups
# is combined with posthoc analysis between each set of the separate groups.
# The omnibus test's adjusted p-value and rejection flag are in `padj` and
# `rejected`; pairwise posthoc results use `posthoc pvalue adj` and
# `posthoc rejected`.
# `Method` records the selected omnibus test (`One-way anova` here); use
# `run_ancova` when covariates should be included in the omnibus model.
#
# The function is the same as for the two groups case. The `group1` and
# `group2` columns give the posthoc comparison.
# `group2` columns give the posthoc comparison, also available as
# `posthoc comparison` in the form `group1~~group2`.
#

# %% tags=["hide-output"]
Expand Down Expand Up @@ -53,7 +59,6 @@
factor_and_covars: list[str] = [group, *covariates]

# %% [markdown]
# # ANOVA analysis for two groups
# Use combined dataset for ANOVA analysis.

# %% tags=["hide-input"]
Expand Down Expand Up @@ -83,8 +88,18 @@


# %% [markdown]
# ## With four groups
# Acore make each combinatorial comparison between groups in the group column.
# # Run ANOVA with four groups
# Acore runs an omnibus test asking if any of the groups are significantly different, so
# if a feature as any effect (F-test between a regression with group dummies and without
# any) and also runs pairwise (posthoc) tests to identify which groups are different and
# in which direction. The omnibus test's adjusted p-value and rejection flag are in
# `padj` and `rejected`; pairwise posthoc results use `posthoc pvalue adj` and `posthoc
# rejected`. `Method` records the selected omnibus test (`One-way anova` here); use
# `run_ancova` when covariates should be included in the omnibus model.
#
# The function is the same as for the two groups case. The `group1` and `group2` columns
# give the posthoc comparison, also available as `posthoc comparison` in the form
# `group1~~group2`.


# %%
Expand All @@ -102,12 +117,14 @@
anova.head().T

# %% [markdown]
# ### pairwise t-test results:
# ## pairwise (posthoc) t-test results
# posthoc t-test results to identify which groups are different and in which direction.

# %% tags=["hide-input"]
cols_pairwise_ttest = [
# "group1",
# "group2",
"posthoc comparison",
"mean(group1)",
"std(group1)",
"mean(group2)",
Expand All @@ -119,6 +136,7 @@
"posthoc tail",
"posthoc pvalue",
"posthoc pvalue adj",
"posthoc rejected",
"posthoc BF10",
"posthoc effsize",
# "identifier",
Expand All @@ -143,23 +161,28 @@
view

# %% [markdown]
# ## Volcano plot of ANOVA results
# - volcano plot of ANOVA (omnibus test) results
# - more than one group present in the example.
# ## Posthoc volcano plot: WRP versus WT
# Select one pairwise comparison so each identifier has one point.
# The x-axis shows its `log2FC`, the y-axis its posthoc p-value, and
# the color its posthoc FDR significance decision (`posthoc rejected`).
# Change `comparison` to another value from the `posthoc comparison` column.


# %% tags=["hide-input"]
comparison = "WRP~~WT"
pairwise_results = anova.loc[anova["posthoc comparison"] == comparison].reset_index()

scatter_plot_adv = vuecore.plots.basic.scatter.create_scatter_plot(
data=anova.reset_index(),
data=pairwise_results,
x="log2FC",
y="-log10 pvalue",
color="rejected",
title="Simple Volcano Plot",
subtitle="Visualizing ANOVA results",
y="-log10 posthoc pvalue",
color="posthoc rejected",
title="Posthoc Volcano Plot",
subtitle=comparison.replace("~~", " versus "),
labels={
"log2FC": "Log2 Fold Change",
"-log10 pvalue": "-log10(p-value)",
"rejected": "FDR corrected Significant",
"log2FC": f"log2 fold change ({comparison.replace('~~', ' / ')})",
"-log10 posthoc pvalue": "-log10(posthoc p-value)",
"posthoc rejected": "Posthoc FDR corrected significant",
"identifier": "Protein Identifier",
},
hover_data=["identifier", "group1", "group2"],
Expand Down
3 changes: 2 additions & 1 deletion docs/markdown_ref/acore.differential_regulation.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,8 @@ if permutations>0 and Benjamini/Hochberg if permutations=0.
* **non_par** ([*bool*](https://docs.python.org/3/builtins/functions.html#bool)) – if True, normality and variance equality assumptions are checked
and non-parametric test Mann Whitney U test if not passed
* **Returns:**
DataFrame adhering to AnovaSchema or AnovaSchemaMultiGroup.
DataFrame adhering to AnovaSchema or AnovaSchemaMultiGroup. For more than
two groups, `posthoc comparison` labels each pair as `group1~~group2`.
* **Return type:**
DataFrame[[AnovaSchema](acore.types.md#acore.types.differential_analysis.AnovaSchema)] | DataFrame[[AnovaSchemaMultiGroup](acore.types.md#acore.types.differential_analysis.AnovaSchemaMultiGroup)]

Expand Down
4 changes: 4 additions & 0 deletions docs/markdown_ref/acore.md
Original file line number Diff line number Diff line change
Expand Up @@ -220,10 +220,12 @@
* [`AnovaSchema.to_yaml()`](acore.types.md#acore.types.differential_analysis.AnovaSchema.to_yaml)
* [`AnovaSchema.validate()`](acore.types.md#acore.types.differential_analysis.AnovaSchema.validate)
* [`AnovaSchemaMultiGroup`](acore.types.md#acore.types.differential_analysis.AnovaSchemaMultiGroup)
* [`AnovaSchemaMultiGroup.posthoc_comparison`](acore.types.md#acore.types.differential_analysis.AnovaSchemaMultiGroup.posthoc_comparison)
* [`AnovaSchemaMultiGroup.t_statistics`](acore.types.md#acore.types.differential_analysis.AnovaSchemaMultiGroup.t_statistics)
* [`AnovaSchemaMultiGroup.posthoc_pvalue`](acore.types.md#acore.types.differential_analysis.AnovaSchemaMultiGroup.posthoc_pvalue)
* [`AnovaSchemaMultiGroup.f_statistics`](acore.types.md#acore.types.differential_analysis.AnovaSchemaMultiGroup.f_statistics)
* [`AnovaSchemaMultiGroup.posthoc_padj`](acore.types.md#acore.types.differential_analysis.AnovaSchemaMultiGroup.posthoc_padj)
* [`AnovaSchemaMultiGroup.posthoc_rejected`](acore.types.md#acore.types.differential_analysis.AnovaSchemaMultiGroup.posthoc_rejected)
* [`AnovaSchemaMultiGroup.posthoc_paired`](acore.types.md#acore.types.differential_analysis.AnovaSchemaMultiGroup.posthoc_paired)
* [`AnovaSchemaMultiGroup.posthoc_parametric`](acore.types.md#acore.types.differential_analysis.AnovaSchemaMultiGroup.posthoc_parametric)
* [`AnovaSchemaMultiGroup.posthoc_dof`](acore.types.md#acore.types.differential_analysis.AnovaSchemaMultiGroup.posthoc_dof)
Expand Down Expand Up @@ -260,8 +262,10 @@
* [`AnovaSchemaMultiGroup.to_yaml()`](acore.types.md#acore.types.differential_analysis.AnovaSchemaMultiGroup.to_yaml)
* [`AnovaSchemaMultiGroup.validate()`](acore.types.md#acore.types.differential_analysis.AnovaSchemaMultiGroup.validate)
* [`AncovaSchema`](acore.types.md#acore.types.differential_analysis.AncovaSchema)
* [`AncovaSchema.posthoc_comparison`](acore.types.md#acore.types.differential_analysis.AncovaSchema.posthoc_comparison)
* [`AncovaSchema.t_statistics`](acore.types.md#acore.types.differential_analysis.AncovaSchema.t_statistics)
* [`AncovaSchema.posthoc_pvalue`](acore.types.md#acore.types.differential_analysis.AncovaSchema.posthoc_pvalue)
* [`AncovaSchema.posthoc_rejected`](acore.types.md#acore.types.differential_analysis.AncovaSchema.posthoc_rejected)
* [`AncovaSchema.coef`](acore.types.md#acore.types.differential_analysis.AncovaSchema.coef)
* [`AncovaSchema.std_err`](acore.types.md#acore.types.differential_analysis.AncovaSchema.std_err)
* [`AncovaSchema.conf_int_low`](acore.types.md#acore.types.differential_analysis.AncovaSchema.conf_int_low)
Expand Down
20 changes: 14 additions & 6 deletions docs/markdown_ref/acore.types.md
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ Load a schema from YAML.
* **Returns:**
the backend-specific schema object.

#### *classmethod* get_metadata() → [dict](https://docs.python.org/3/builtins/stdtypes.html#dict) | [None](https://docs.python.org/3/builtins/constants.html#None)
#### *classmethod* get_metadata() → [dict](https://docs.python.org/3/builtins/stdtypes.html#dict)[[Any](https://docs.python.org/3/library/typing.html#typing.Any), [Any](https://docs.python.org/3/library/typing.html#typing.Any)]

Provide metadata for columns and schema level

Expand Down Expand Up @@ -267,6 +267,8 @@ Bases: [`AnovaSchema`](#acore.types.differential_analysis.AnovaSchema)

Schema for more than two groups

#### posthoc_comparison *: [str](https://docs.python.org/3/builtins/stdtypes.html#str)* *= 'posthoc comparison'*

#### t_statistics *: [float](https://docs.python.org/3/builtins/functions.html#float)* *= 'posthoc T-Statistics'*

#### posthoc_pvalue *: [float](https://docs.python.org/3/builtins/functions.html#float)* *= 'posthoc pvalue'*
Expand All @@ -275,6 +277,8 @@ Schema for more than two groups

#### posthoc_padj *: [float](https://docs.python.org/3/builtins/functions.html#float)* *= 'posthoc pvalue adj'*

#### posthoc_rejected *: [bool](https://docs.python.org/3/builtins/functions.html#bool)* *= 'posthoc rejected'*

#### posthoc_paired *: [bool](https://docs.python.org/3/builtins/functions.html#bool)* *= 'posthoc Paired'*

#### posthoc_parametric *: [bool](https://docs.python.org/3/builtins/functions.html#bool)* *= 'posthoc Parametric'*
Expand Down Expand Up @@ -437,7 +441,7 @@ Load a schema from YAML.
* **Returns:**
the backend-specific schema object.

#### *classmethod* get_metadata() → [dict](https://docs.python.org/3/builtins/stdtypes.html#dict) | [None](https://docs.python.org/3/builtins/constants.html#None)
#### *classmethod* get_metadata() → [dict](https://docs.python.org/3/builtins/stdtypes.html#dict)[[Any](https://docs.python.org/3/library/typing.html#typing.Any), [Any](https://docs.python.org/3/library/typing.html#typing.Any)]

Provide metadata for columns and schema level

Expand Down Expand Up @@ -525,10 +529,14 @@ Bases: [`DataFrameModel`](https://pandera.readthedocs.io/en/stable/reference/gen

Schema for the enrichment analysis results DataFrame.

#### posthoc_comparison *: [str](https://docs.python.org/3/builtins/stdtypes.html#str)* *= 'posthoc comparison'*

#### t_statistics *: [float](https://docs.python.org/3/builtins/functions.html#float)* *= 'posthoc T-Statistics'*

#### posthoc_pvalue *: [float](https://docs.python.org/3/builtins/functions.html#float)* *= 'posthoc pvalue'*

#### posthoc_rejected *: [bool](https://docs.python.org/3/builtins/functions.html#bool)* *= 'posthoc rejected'*

#### coef *: [float](https://docs.python.org/3/builtins/functions.html#float)* *= 'coef'*

#### std_err *: [float](https://docs.python.org/3/builtins/functions.html#float)* *= 'std err'*
Expand Down Expand Up @@ -683,7 +691,7 @@ Load a schema from YAML.
* **Returns:**
the backend-specific schema object.

#### *classmethod* get_metadata() → [dict](https://docs.python.org/3/builtins/stdtypes.html#dict) | [None](https://docs.python.org/3/builtins/constants.html#None)
#### *classmethod* get_metadata() → [dict](https://docs.python.org/3/builtins/stdtypes.html#dict)[[Any](https://docs.python.org/3/library/typing.html#typing.Any), [Any](https://docs.python.org/3/library/typing.html#typing.Any)]

Provide metadata for columns and schema level

Expand Down Expand Up @@ -915,7 +923,7 @@ Load a schema from YAML.
* **Returns:**
the backend-specific schema object.

#### *classmethod* get_metadata() → [dict](https://docs.python.org/3/builtins/stdtypes.html#dict) | [None](https://docs.python.org/3/builtins/constants.html#None)
#### *classmethod* get_metadata() → [dict](https://docs.python.org/3/builtins/stdtypes.html#dict)[[Any](https://docs.python.org/3/library/typing.html#typing.Any), [Any](https://docs.python.org/3/library/typing.html#typing.Any)]

Provide metadata for columns and schema level

Expand Down Expand Up @@ -1131,7 +1139,7 @@ Load a schema from YAML.
* **Returns:**
the backend-specific schema object.

#### *classmethod* get_metadata() → [dict](https://docs.python.org/3/builtins/stdtypes.html#dict) | [None](https://docs.python.org/3/builtins/constants.html#None)
#### *classmethod* get_metadata() → [dict](https://docs.python.org/3/builtins/stdtypes.html#dict)[[Any](https://docs.python.org/3/library/typing.html#typing.Any), [Any](https://docs.python.org/3/library/typing.html#typing.Any)]

Provide metadata for columns and schema level

Expand Down Expand Up @@ -1341,7 +1349,7 @@ Load a schema from YAML.
* **Returns:**
the backend-specific schema object.

#### *classmethod* get_metadata() → [dict](https://docs.python.org/3/builtins/stdtypes.html#dict) | [None](https://docs.python.org/3/builtins/constants.html#None)
#### *classmethod* get_metadata() → [dict](https://docs.python.org/3/builtins/stdtypes.html#dict)[[Any](https://docs.python.org/3/library/typing.html#typing.Any), [Any](https://docs.python.org/3/library/typing.html#typing.Any)]

Provide metadata for columns and schema level

Expand Down
3 changes: 2 additions & 1 deletion src/acore/differential_regulation/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,8 @@ def run_anova(
:param bool is_logged: whether data is log-transformed
:param bool non_par: if True, normality and variance equality assumptions are checked
and non-parametric test Mann Whitney U test if not passed
:return: DataFrame adhering to AnovaSchema or AnovaSchemaMultiGroup.
:return: DataFrame adhering to AnovaSchema or AnovaSchemaMultiGroup. For more than
two groups, ``posthoc comparison`` labels each pair as ``group1~~group2``.
:rtype: DataFrame[AnovaSchema] | DataFrame[AnovaSchemaMultiGroup]

Example::
Expand Down
4 changes: 4 additions & 0 deletions src/acore/differential_regulation/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,10 @@ def format_anova_table(
res["log2FC"] = np.nan

res = res.reset_index()
if {"group1", "group2"}.issubset(res.columns):
res["posthoc comparison"] = (
res["group1"].astype(str) + "~~" + res["group2"].astype(str)
)
res["rejected"] = res["padj"] < alpha
# ! double check this
if "posthoc pvalue" in res.columns:
Expand Down
16 changes: 13 additions & 3 deletions src/acore/multiple_testing/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -213,12 +213,22 @@ def correct_pairwise_ttest(df, alpha, correction="fdr_bh", pvalue_col="posthoc p
for comparison in df.groupby(["group1", "group2"]).groups:
index = df.groupby(["group1", "group2"]).groups.get(comparison)
posthoc_pvalues = df.loc[index, pvalue_col].tolist()
_, _padj = apply_pvalue_correction(
rejected, padj = apply_pvalue_correction(
posthoc_pvalues, alpha=alpha, method=correction
)

_posthoc_df = pd.DataFrame({"index": index, f"{pvalue_col} adj": _padj})
posthoc_df.append(_posthoc_df)
posthoc_df.append(
pd.DataFrame(
{
"index": index,
f"{pvalue_col} adj": padj,
"posthoc rejected": pd.Series(rejected)
.fillna(False)
.astype(bool)
.to_numpy(),
}
)
)
posthoc_df = pd.concat(posthoc_df)
posthoc_df = posthoc_df.set_index("index")
df = df.join(posthoc_df)
Expand Down
Loading
Loading