You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在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]
}

关键修正点

  1. 对齐日期:通过merge函数只保留个股和指数都交易的日期,确保回归变量长度一致
  2. 改用收益率回归:市场模型的正确输入是收益率(而非价格),避免回归逻辑错误
  3. 修正日期解析:将as.date改为R标准的as.Date函数,确保日期格式正确
  4. 处理异常情况:添加数据量检查,避免因数据不足导致的报错
  5. 定义缺失变量:补充market_return的逻辑,改用匹配后的指数收益率

内容的提问来源于stack exchange,提问作者Simon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 15:45:52