Python中Friedman检验及Dunn事后检验分析差异蛋白遇阻求助
问题:Friedman检验结合Dunn事后检验分析蛋白差异的代码报错排查及方法推荐
我想用Friedman检验识别有统计显著性的蛋白,数据集是多次试验汇总的中位数,包含两种独立培养基及各自对照组,收集了特定时间段内各培养基的蛋白含量,目标是对比两种培养基,找出含量有统计差异的蛋白。
我尝试先做Friedman检验,再用Dunn事后检验,但代码运行失败,希望帮忙排查问题,也欢迎推荐适合的其他统计方法。
原代码
import numpy as np # linear algebra import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv) from scipy.stats import friedmanchisquare from scikit_posthocs import posthoc_dunn # Sample data data = { 'Protein': ['Protein1', 'Protein2', 'Protein3', 'Protein4', 'Protein5'], 'Control_Medium1': [1.0, 1.1, 1.2, 1.0, 1.3], 'Control_Medium2': [1.1, 1.0, 1.1, 1.2, 1.0], 'Medium1_T1': [1.5, 1.5, 1.8, 2.0, 1.6], 'Medium1_T2': [1.2, 1.3, 1.7, 1.9, 2.1], 'Medium1_T3': [1.1, 1.6, 1.9, 1.4, 1.7], 'Medium2_T1': [0.1, 1.2, 1.7, 1.8, 1.5], 'Medium2_T2': [0.2, 1.4, 1.8, 1.7, 1.9], 'Medium2_T3': [0.3, 1.5, 1.3, 1.7, 1.4], } df = pd.DataFrame(data) # Perform Friedman test control_medium1 = df['Control_Medium1'] control_medium2 = df['Control_Medium2'] medium1_t1 = df['Medium1_T1'] medium1_t2 = df['Medium1_T2'] medium1_t3 = df['Medium1_T3'] medium2_t1 = df['Medium2_T1'] medium2_t2 = df['Medium2_T2'] medium2_t3 = df['Medium2_T3'] _, p_value = friedmanchisquare(control_medium1, control_medium2, medium1_t1, medium1_t2, medium1_t3, medium2_t1, medium2_t2, medium2_t3) # Print Friedman test result print('Friedman Test:') print('p-value:', p_value) # Perform pairwise comparisons with posthoc test data_for_posthoc = [medium1_t1, medium1_t2, medium1_t3, medium2_t1, medium2_t2, medium2_t3] labels_for_posthoc = ['Medium1_T1', 'Medium1_T2', 'Medium1_T3', 'Medium2_T1', 'Medium2_T2', 'Medium2_T3'] posthoc_result = sp.posthoc_dunn(data_for_posthoc) # Apply Bonferroni correction to p-values alpha = 0.05 corrected_p_values = np.multiply(posthoc_result, len(posthoc_result.columns)) # Get the significantly different proteins significant_proteins = [] for protein in df.columns[1:]: if any(corrected_p_values[protein] < alpha): significant_proteins.append(protein) print('Significant Proteins:', significant_proteins)
代码问题排查
- 导入引用错误:代码中使用
sp.posthoc_dunn调用函数,但导入语句是from scikit_posthocs import posthoc_dunn,应直接使用posthoc_dunn,无需前缀sp.。 - Friedman检验输入逻辑错误:
scipy.stats.friedmanchisquare要求输入为同一受试对象的重复测量数据(行对应受试对象,列对应不同处理/时间点)。但当前数据行是蛋白,列是不同培养基/时间点,把所有蛋白的测量值混在一起做整体检验,不符合Friedman检验的配伍组设计逻辑——你的目标是找出不同培养基中含量有差异的蛋白,应该针对每个蛋白单独做检验。 - 事后检验数据结构错误:
posthoc_dunn需要结合试验设计的分组/区组信息,当前输入的是各列数据的列表,未考虑蛋白作为区组,且没有使用长格式数据,导致检验结果无法对应到蛋白层面。 - 显著蛋白判断逻辑错误:
corrected_p_values是培养基/时间点的两两比较矩阵,而非蛋白层面的结果,循环遍历df.columns[1:](培养基列)来筛选蛋白,逻辑完全错位。
修正后的代码示例
import numpy as np import pandas as pd from scipy.stats import friedmanchisquare from scikit_posthocs import posthoc_dunn # 样本数据 data = { 'Protein': ['Protein1', 'Protein2', 'Protein3', 'Protein4', 'Protein5'], 'Control_Medium1': [1.0, 1.1, 1.2, 1.0, 1.3], 'Control_Medium2': [1.1, 1.0, 1.1, 1.2, 1.0], 'Medium1_T1': [1.5, 1.5, 1.8, 2.0, 1.6], 'Medium1_T2': [1.2, 1.3, 1.7, 1.9, 2.1], 'Medium1_T3': [1.1, 1.6, 1.9, 1.4, 1.7], 'Medium2_T1': [0.1, 1.2, 1.7, 1.8, 1.5], 'Medium2_T2': [0.2, 1.4, 1.8, 1.7, 1.9], 'Medium2_T3': [0.3, 1.5, 1.3, 1.7, 1.4], } df = pd.DataFrame(data) alpha = 0.05 significant_proteins = [] # 针对每个蛋白单独分析 for _, row in df.iterrows(): protein_name = row['Protein'] # 获取该蛋白在所有处理组的测量值 values = row[1:].values group_names = df.columns[1:] # 执行Friedman检验:每个蛋白作为一个受试对象,各处理组为重复测量 _, p_val = friedmanchisquare(*values) if p_val < alpha: # 转成长格式数据用于事后检验 protein_df = pd.DataFrame({ 'group': group_names, 'value': values }) # 执行Dunn事后检验,使用Bonferroni校正 posthoc_results = posthoc_dunn(protein_df, val_col='value', group_col='group', p_adjust='bonferroni') # 检查Medium1与Medium2组间的两两比较是否存在显著差异 medium1_groups = [g for g in group_names if 'Medium1' in g] medium2_groups = [g for g in group_names if 'Medium2' in g] has_diff = False for m1 in medium1_groups: for m2 in medium2_groups: if posthoc_results.loc[m1, m2] < alpha: has_diff = True break if has_diff: break if has_diff: significant_proteins.append(protein_name) print('具有显著差异的蛋白:', significant_proteins)
适用统计方法推荐
- 独立样本场景:如果不同培养基是独立培养体系(蛋白测量来自不同样本),Friedman检验不适用,建议使用Kruskal-Wallis H检验(非参数版单因素ANOVA),后续用Dunn或Tukey事后检验做两两比较。
- 重复测量场景:如果是同一培养体系在不同时间点测量同一蛋白,Friedman检验是合适的,事后检验可选择Dunn检验或Conover检验。
- 多检验校正:由于需要对多个蛋白进行检验,建议使用Bonferroni或FDR(错误发现率)校正整体α水平,降低假阳性概率。
内容的提问来源于stack exchange,提问作者planckton
相关产品推荐
相关产品推荐

