在R Studio计算买入持有超额收益(BHAR)遇变量长度错误求助
问题:计算BHAR时出现变量长度不匹配错误
背景
我正尝试为具有不同事件日期的股票样本计算买入持有超额收益(BHAR),alpha和beta通过事件日期前11天开始的252个交易日估计期,将个股数据与市场代理数据回归得到。现有三个数据框:
index_data:包含市场指数价格与日期stock_data:包含个股代码、日期及收盘价event_data:包含事件日期与对应个股代码
我的逻辑是:遍历event_data中的每个条目,计算估计期起止日期,在估计期内拟合个股与指数的线性回归模型,提取alpha和beta,在stock_data中新增列计算预期收益,最后通过实际收益与预期收益的累积乘积之差计算BHAR。
编写的R代码
# Loop through the tickers in ticker_BHAR for (ticker in event_data$Ticker[1:19]) { # Get the event date for the current ticker event_date <- as.date(event_data$date[event_data$Ticker == ticker], format = "%d-%m-%Y") # Compute the start and end dates for the estimation window start_date <- event_date - 265 - 11 end_date <- event_date - 11 # Subset the stock_data and index_data dataframes to only include the dates in the estimation window stock_subset <- stock_data[stock_data$Ticker == ticker & stock_data$date >= start_date & stock_data$date <= end_date, ] index_subset <- index_data[index_data$date >= start_date & index_data$date <= end_date, ] # Fit a linear regression model between the stock and index data model <- lm(stock_subset$adjusted ~ index_subset$close) # Extract the alpha and beta coefficients from the model alpha <- coef(model)[1] beta <- coef(model)[2] # Compute the expected return for the current ticker and add it to the stock_data dataframe stock_data[stock_data$Ticker == ticker, "expected_return"] <- alpha + beta * market_return }
错误信息
Error in model.frame.default(formula = stock_subset$adjusted ~ index_subset$close, : variables length differ (found for 'index_subset$close')
解决方案
错误原因
个股数据和指数数据在估计期内的日期不匹配(比如个股存在停牌日,而指数正常交易),导致两个子集的行数不一致,无法进行线性回归。
修正后的代码
# 统一日期格式为Date类型,避免解析错误 stock_data$date <- as.Date(stock_data$date, format = "%d-%m-%Y") index_data$date <- as.Date(index_data$date, format = "%d-%m-%Y") event_data$date <- as.Date(event_data$date, format = "%d-%m-%Y") # 遍历event_data中的个股 for (ticker in event_data$Ticker[1:19]) { # 获取当前个股的事件日期 event_date <- event_data$date[event_data$Ticker == ticker] # 计算估计期起止日期(注:后续建议改用交易日计数,而非自然日) start_date <- event_date - 265 - 11 end_date <- event_date - 11 # 提取个股和指数的估计期原始数据 stock_subset <- stock_data[stock_data$Ticker == ticker & stock_data$date >= start_date & stock_data$date <= end_date, ] index_subset <- index_data[index_data$date >= start_date & index_data$date <= end_date, ] # 按日期合并数据,只保留两者都存在的交易日 merged_data <- merge(stock_subset, index_subset, by = "date", all = FALSE) # 检查合并后数据量是否满足回归要求 if(nrow(merged_data) < 2) { warning(paste("个股", ticker, "估计期有效数据不足,跳过")) next } # 计算收益率(市场模型需用收益率而非价格回归) merged_data$stock_return <- c(NA, diff(log(merged_data$adjusted))) merged_data$index_return <- c(NA, diff(log(merged_data$close))) # 去除含NA的行 merged_data_clean <- na.omit(merged_data) # 拟合市场模型 model <- lm(stock_return ~ index_return, data = merged_data_clean) # 提取alpha和beta alpha <- coef(model)[1] beta <- coef(model)[2] # 给index_data添加指数收益率列 if(!"index_return" %in% colnames(index_data)) { index_data$index_return <- c(NA, diff(log(index_data$close))) } # 合并个股数据与指数收益率,计算预期收益 stock_data <- merge(stock_data, index_data[, c("date", "index_return")], by = "date", all.x = TRUE) stock_data$expected_return[stock_data$Ticker == ticker] <- alpha + beta * stock_data$index_return[stock_data$Ticker == ticker] }
关键修正点
- 对齐日期:通过
merge函数只保留个股和指数都交易的日期,确保回归变量长度一致 - 改用收益率回归:市场模型的正确输入是收益率(而非价格),避免回归逻辑错误
- 修正日期解析:将
as.date改为R标准的as.Date函数,确保日期格式正确 - 处理异常情况:添加数据量检查,避免因数据不足导致的报错
- 定义缺失变量:补充
market_return的逻辑,改用匹配后的指数收益率
内容的提问来源于stack exchange,提问作者Simon
相关产品推荐
相关产品推荐

