103 lines
3.5 KiB
Python
103 lines
3.5 KiB
Python
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!")
|