基于分类变量的R数据框值序列计算与天气预测算法回测求助
嘿,我来帮你搞定这两个R的问题!先逐个拆解说明,结合你熟悉的data.table来实现~
问题1:基于分类变量的序列变化计算
首先咱们先把你提供的部分数据整理成可操作的data.table格式(方便后续处理):
library(data.table) dt <- data.table( Time = 1:8, TempC = c(25.0, 25.2, 25.6, 25.0, 24.7, 23.6, 28.9, 30.0), Index1 = c("Up", "Up", "Up", "Down", "Down", "Down", "Up", "Up"), Index2 = c("Down", "Up", "Up", "Down", "Down", "Down", "Up", "Up"), Index3 = c("Down", "Up", "Up", "Down", "Down", "Down", "Up", "Up"), Index4 = c("Down", "Down", "Up", "Up", "Down", "Down", "Down", "Up") )
场景1:计算连续分类状态的长度
比如想知道每个Index列中,连续出现Up或Down的次数,可以用data.table的rleid()函数生成序列ID,再按ID分组统计长度:
# 以Index1为例,生成连续状态的序列ID dt[, Index1_seq_id := rleid(Index1)] # 计算每个连续序列的长度 dt[, Index1_seq_length := .N, by = Index1_seq_id]
执行后你会看到新增两列:Index1_seq_id标记每个连续状态组的编号,Index1_seq_length是该组的连续次数。如果要批量处理所有Index列,可以用循环或者lapply:
index_cols <- grep("^Index", names(dt), value = TRUE) lapply(index_cols, function(col) { dt[, paste0(col, "_seq_id") := rleid(get(col))] dt[, paste0(col, "_seq_length") := .N, by = paste0(col, "_seq_id")] })
场景2:检测分类状态的变化次数
如果想统计相邻行中状态切换的次数(比如从Up变Down),可以用shift()函数获取前一行的状态,再对比:
# 以Index1为例,获取前一行的状态 dt[, Index1_prev := shift(Index1)] # 标记是否发生状态变化(第一行无前置状态,标记为FALSE) dt[, Index1_change := ifelse(is.na(Index1_prev), FALSE, Index1 != Index1_prev)] # 统计总变化次数 total_changes <- dt[, sum(Index1_change, na.rm = TRUE)]
注意:以上逻辑可以根据你的实际需求调整,比如你需要的是其他类型的序列变化计算,可以随时修改判断规则~
问题2:多指标组合的算法回测
针对天气预测指标的组合回测,我们可以分三步实现:生成所有指标组合、定义回测策略函数、批量执行回测并整理结果。
步骤1:生成所有指标组合
先提取所有指标列,然后生成从1个到4个指标的所有非空组合:
# 提取所有Index列 index_cols <- grep("^Index", names(dt), value = TRUE) # 生成所有组合(需要先安装combinat包) install.packages("combinat") library(combinat) all_combinations <- unlist(lapply(1:length(index_cols), function(k) { combn(index_cols, k, simplify = FALSE) }), recursive = FALSE)
步骤2:定义回测策略函数
这里假设一个简单的策略:当组合内所有指标都为Up时做多,所有指标都为Down时做空,否则持有。你可以根据实际的预测逻辑修改信号规则:
backtest_strategy <- function(dt, index_combo) { # 复制数据避免修改原表 dt_temp <- copy(dt) # 生成交易信号:1=做多,-1=做空,0=持有 dt_temp[, signal := ifelse( rowSums(.SD == "Up") == length(index_combo), 1, ifelse(rowSums(.SD == "Down") == length(index_combo), -1, 0) ), .SDcols = index_combo] # 计算收益(这里用TempC的下期变化率模拟,你可以替换成实际的预测目标收益) dt_temp[, return := shift(TempC, type = "lead") / TempC - 1] # 计算策略收益:信号 × 下期收益 dt_temp[, strategy_return := signal * return] # 计算累计收益 dt_temp[, cumulative_return := cumprod(1 + strategy_return, na.rm = TRUE)] # 返回关键回测指标 list( 指标组合 = paste(index_combo, collapse = "+"), 累计收益 = last(dt_temp$cumulative_return, na.rm = TRUE), 胜率 = sum(strategy_return > 0, na.rm = TRUE) / sum(!is.na(strategy_return)), 最大回撤 = min(dt_temp$cumulative_return / cummax(dt_temp$cumulative_return) - 1, na.rm = TRUE) ) }
步骤3:批量执行回测并查看结果
循环所有指标组合,执行回测后整理成表格:
# 执行所有组合的回测 backtest_results <- lapply(all_combinations, function(combo) { backtest_strategy(dt, combo) }) # 转换为data.table方便查看排序 results_dt <- rbindlist(backtest_results) # 按累计收益从高到低排序 results_dt[order(-累计收益)]
这样你就能直观看到每个指标组合的回测表现,方便筛选最优组合啦~
内容的提问来源于stack exchange,提问作者civy
相关产品推荐
相关产品推荐

