R语言事件研究如何将聚合、t检验等步骤集成到自定义函数自动输出结果表
事件研究自定义函数整合实现方案
1. 函数重构核心思路
- 输入参数保留原有
event_up的必要参数,新增s(评级变动阈值)、event_window(事件窗口,传入起止元组更灵活,例如(-2,2)代表事件日前2天到后2天)、target_table(目标表格的引用,方便直接写入计算结果) - 内部逻辑按你提到的分析步骤模块化封装,避免重复编写冗余代码
2. 重构后的event_up函数代码示例
import pandas as pd from scipy import stats def event_up(raw_data, s, event_window, est_window=(-120,-11), target_table=None): # raw_data:原始数据集,需包含ISIN、事件日、相对时间、个股收益率、市场收益率等必要字段 # s:评级变动阈值,仅保留评级变动绝对值≥s的事件样本 # event_window:事件窗口元组,例如(-2,2)代表事件日前后2天的窗口 # est_window:估计窗口元组,默认用事件日前120天到前11天计算正常收益 # target_table:预设结构的TR_CAAR_table数据框,用于存储最终结果 # 步骤1:按评级变动阈值筛选有效事件 filtered_events = raw_data[raw_data['评级变动绝对值'] >= s].copy() # 步骤2:ISIN维度聚合收益率数据 isin_grouped = filtered_events.groupby(['ISIN', '事件日', '相对时间'], as_index=False)[['个股收益率', '市场收益率']].mean() # 步骤3:删除冗余列,仅保留分析用字段 isin_grouped = isin_grouped[['ISIN', '事件日', '相对时间', '个股收益率', '市场收益率']] # 步骤4:基于估计窗口拟合市场模型计算正常收益 est_sample = isin_grouped[(isin_grouped['相对时间'] >= est_window[0]) & (isin_grouped['相对时间'] <= est_window[1])] def calc_normal_return(group): # 拟合市场模型R_i = α + β*R_m beta, alpha = stats.linregress(group['市场收益率'], group['个股收益率'])[0:2] # 给当前事件所有时间点拼接正常收益 event_all = isin_grouped[(isin_grouped['ISIN'] == group.name[0]) & (isin_grouped['事件日'] == group.name[1])].copy() event_all['正常收益'] = alpha + beta * event_all['市场收益率'] return event_all ar_df = est_sample.groupby(['ISIN', '事件日']).apply(calc_normal_return).reset_index(drop=True) # 步骤5:计算异常收益AR、累计异常收益CAR ar_df['AR'] = ar_df['个股收益率'] - ar_df['正常收益'] window_sample = ar_df[(ar_df['相对时间'] >= event_window[0]) & (ar_df['相对时间'] <= event_window[1])] car_df = window_sample.groupby(['ISIN', '事件日'], as_index=False)['AR'].sum().rename(columns={'AR': 'CAR'}) # 步骤6:计算累计平均异常收益CAAR + 单样本t检验 caar = car_df['CAR'].mean() t_stat, p_value = stats.ttest_1samp(car_df['CAR'], popmean=0) sample_n = len(car_df) # 步骤7:自动写入目标TR_CAAR_table if target_table is not None: row_loc = (target_table['评级变动阈值'] == s) & (target_table['事件窗口'] == f"{event_window[0]}~{event_window[1]}") target_table.loc[row_loc, 'CAAR'] = round(caar, 4) target_table.loc[row_loc, 't统计量'] = round(t_stat, 4) target_table.loc[row_loc, 'p值'] = round(p_value, 4) target_table.loc[row_loc, '有效样本量'] = sample_n # 所有中间结果返回供额外分析使用 return {'CAAR': caar, 't_stat': t_stat, 'p_value': p_value, 'sample_n': sample_n, 'CAR明细': car_df, '更新后目标表': target_table}
3. 批量调用示例
# 第一步:按预设结构初始化目标表格TR_CAAR_table TR_CAAR_table = pd.DataFrame(columns=['评级变动阈值', '事件窗口', 'CAAR', 't统计量', 'p值', '有效样本量']) # 填入所有需要测试的阈值+窗口组合 test_params = [(1, (-1,1)), (1, (-2,2)), (2, (-1,1)), (2, (-2,2))] for s, w in test_params: TR_CAAR_table.loc[len(TR_CAAR_table)] = [s, f"{w[0]}~{w[1]}", None, None, None, None] # 第二步:批量执行分析,自动填充结果 for s, w in test_params: res = event_up(raw_data=你的原始数据集, s=s, event_window=w, target_table=TR_CAAR_table) TR_CAAR_table = res['更新后目标表'] # 查看最终填充完成的表格 print(TR_CAAR_table)
4. 适配注意事项
- 代码中的字段名(例如
评级变动绝对值、个股收益率、相对时间等)需要和你实际数据集的字段名保持一致,不匹配的话提前修改对应字段名称即可 - 如果你已经提前算完正常收益,可以删除函数内拟合市场模型的模块,直接用你预处理好的AR数据计算即可
- 如果需要用非参数检验替代默认的t检验,把
stats.ttest_1samp替换为对应的非参数检验方法(例如秩和检验)即可
内容的提问来源于stack exchange,提问作者antonia_pi
相关产品推荐
相关产品推荐

