将高血压患者随机分为2组
一组入组16人,使用A药治疗
二组入组6人,使用B药治疗
总共治疗时间为30天
于第31天评估血压达标率
若第31天的血压<140/90,则为血压达标
某组的血压达标率定义为第31天的血压<140/90的人数/该组入组的总人数
试比较两组的血压达标率
方法如下
1、以xlsx格式将数据整理为以下形式,其
中0定义为血压不达标,而1定义为血压达标
group result
A 0
A 0
A 0
A 0
A 0
A 0
A 1
A 1
A 1
A 1
A 1
A 1
A 1
A 1
A 1
A 1
B 0
B 0
B 0
B 0
B 1
B 1
2、根据该数据所在的实际目录位置修改第2行的代码
import pandas as pd
df = pd.read_excel(r"")#######修改
from scipy.stats import chi2_contingency,fisher_exact
from itertools import chain
def chi2_fisher(y,x,df): # chi2_fisher(y和x都是分类变量的列名, df是数据框名),例如chi2_fisher('group','result', df)
print("==============================================================================")
A = pd.crosstab(df[y], df[x])
A_list = A.values.flatten().tolist()
n = sum(A_list)
print(f"实际频数(A)表为:n={n}\n{A}\n")
chi2, P, f, T = chi2_contingency(A, correction = False)
T_list = list(chain(*T))
print(f"理论频数(T)表为:\n{T}\n")
if n>=40 and all(i > 5 for i in T_list):
print('普通χ²检验(n≥40 & 所有T>5):correction= False',
"\nχ²=", chi2,
"\nP=", P,
"\n自由度=", f)
elif (n<40 or any(i < 1 for i in T_list)) and df[y].nunique()==2 and df[x].nunique()==2: # df必须是2*2!!!
oddsratio, P = fisher_exact(A)
print('fisher确切概率必须2*2(n<40 | 有T<1):',
"\noddsratio=", oddsratio,
"\nP=", P)
else:
chi2, P, f, T = chi2_contingency(A, correction = True)
print('校正χ²检验(n≥40 但 1≤T<5):correction= True',
"\nχ²=", chi2,
"\nP=", P,
"\n自由度=", f)
str(A.columns)
A[f'{A.columns[1]}/({A.columns[0]}+{A.columns[1]})'] = A.apply(lambda x: x[A.columns[1]]/(x[A.columns[0]]+x[A.columns[1]]),axis=1)
print(f'\n{A}')
print("==============================================================================")
chi2_fisher('group','result', df) # 修改
3、随后运行这一程序便可以自动进行χ²检验、校正χ²检验、fisher确切概率法。
这一程序可以自动进行χ²检验、校正χ²检验、fisher确切概率法,成功运行这一程序的注意要点有:
1、原数据必须为清洁格式,即
每一列是一个变量
每一行是一个观测
每个单元格是变量的一个值
2、函数pd.read_excel()的参数取值需与xlsx文件所在的实际目录位置保持一致
3、自定义函数chi2_fisher(y,x)的参数y和x的取值,需与原数据的列名保持一致