import sys sys.stdout.reconfigure(encoding='utf-8') import pandas as pd import numpy as np import openpyxl from openpyxl.utils.dataframe import dataframe_to_rows from openpyxl.styles import Font, Alignment import os import shutil base_dir = r'c:\Users\NASPC\Documents\Du án tại SG tháng 8' orig_file = os.path.join(base_dir, 'KẾT QUẢ PHÂN TÍCH.xlsx') final_file = os.path.join(base_dir, 'Project_Code_and_Results', 'KẾT_QUẢ_PHÂN_TÍCH_MASTER.xlsx') # Copy original to new file shutil.copy(orig_file, final_file) # Load workbook wb = openpyxl.load_workbook(final_file) # Helper to process CSV into JASP layout dataframe def get_jasp_df(filepath, model_name="M₁"): df = pd.read_csv(filepath, index_col=0) se_col = 'S.E.' if 'S.E.' in df.columns else ('std err' if 'std err' in df.columns else 'SE') estimate = df['Beta (B)'] se = df[se_col] odds_ratio = df['Odds Ratio EXP(B)'] p_val = df['P-value'] z_stat = estimate / se wald = z_stat ** 2 lower = np.exp(estimate - 1.96 * se) upper = np.exp(estimate + 1.96 * se) def map_name(name): if name == 'const': return '(Intercept)' if '_' in name: parts = name.split('_') return f"{parts[0]} ({parts[1]})" return name new_index = [map_name(str(i)) for i in df.index] out_df = pd.DataFrame({ 'Model': [model_name] + [np.nan] * (len(df) - 1), '': new_index, 'Estimate': estimate.values, 'Standard Error': se.values, 'Odds Ratio': odds_ratio.values, 'z': z_stat.values, 'Wald Statistic': wald.values, 'df': [1] * len(df), 'p': p_val.values, 'Lower bound': lower.values, 'Upper bound': upper.values }) # Format out_df['p'] = out_df['p'].apply(lambda x: '< .00001' if pd.notnull(x) and x < 0.00001 else (round(x, 5) if pd.notnull(x) else x)) out_df = out_df.round(5) return out_df # Replace a sheet's content def replace_sheet(sheet_name, csv_path): idx = wb.sheetnames.index(sheet_name) del wb[sheet_name] ws = wb.create_sheet(sheet_name, idx) # Write Title ws.cell(row=1, column=1, value="Logistic Regression (Updated with Firth/Optimized)").font = Font(bold=True) ws.cell(row=3, column=1, value="Coefficients").font = Font(bold=True) # Headers df_jasp = get_jasp_df(csv_path) headers = list(df_jasp.columns) for c_idx, col_name in enumerate(headers, 1): cell = ws.cell(row=4, column=c_idx, value=col_name) cell.font = Font(bold=True) cell.alignment = Alignment(horizontal='center') ws.cell(row=3, column=10, value="95% Confidence interval").font = Font(bold=True) ws.cell(row=3, column=10).alignment = Alignment(horizontal='center') # Write Data for r_idx, row in enumerate(dataframe_to_rows(df_jasp, index=False, header=False), 5): for c_idx, value in enumerate(row, 1): # Check for NaN float if isinstance(value, float) and np.isnan(value): ws.cell(row=r_idx, column=c_idx, value="") else: ws.cell(row=r_idx, column=c_idx, value=value) path_don = os.path.join(base_dir, 'Project_Code_and_Results', '4_Logistic_Regression', 'Logistic_Results_Donation_Firth.csv') path_dec = os.path.join(base_dir, 'Project_Code_and_Results', '4_Logistic_Regression', 'Logistic_Results_Decision_Final.csv') replace_sheet('Donation', path_don) replace_sheet('Decision', path_dec) wb.save(final_file) print("Tạo thành công MASTER file!")