R语言双递减随机变量赛跑模拟的高效批量实现方法
高效多轮迭代模拟实现方案
你不需要手动逐次执行迭代再手动拼接,把单轮逻辑封装成函数,再用批量迭代工具自动执行+拼接即可,性能比手动操作高几个量级。
核心实现逻辑
- 先封装单轮模拟的函数,自动按规则生成a、b序列,直到任一值≤0时终止
- 再通过批量执行工具重复运行单轮函数,自动合并所有结果,全程不需要手动干预
完整代码
# 加载依赖,dplyr用于数据处理,没有安装可先运行 install.packages("dplyr") library(dplyr) # 单轮模拟函数 # 入参可自定义初始值、步长的均值和标准差 single_run <- function(init = 100, step_mean = 5, step_sd = 10) { current_a <- init current_b <- init step_count <- 1 # 用列表预存每一步结果,比逐行修改数据框快很多 step_res <- list() while (current_a > 0 & current_b > 0) { # 生成正步长,保证序列严格递减:如果抽出来的步长为负就重抽 step_a <- rnorm(1, step_mean, step_sd) while (step_a <= 0) step_a <- rnorm(1, step_mean, step_sd) step_b <- rnorm(1, step_mean, step_sd) while (step_b <= 0) step_b <- rnorm(1, step_mean, step_sd) # 更新当前值 current_a <- current_a - step_a current_b <- current_b - step_b # 存入当前步结果 step_res[[step_count]] <- data.frame( step = step_count, a = current_a, b = current_b ) step_count <- step_count + 1 } # 合并单轮所有步的结果 do.call(rbind, step_res) }
批量执行模拟
比如你需要重复跑1000次模拟,直接运行以下代码即可,最终结果会自动带上sim_id列标记所属的模拟轮次,step列标记当前是该轮的第几步,不需要手动拼接:
# 方法1:base R 实现,不需要额外装包 sim_times <- 1000 # 自定义模拟次数 all_sim_list <- lapply(1:sim_times, function(id) { run_df <- single_run() run_df$sim_id <- id run_df }) final_result <- do.call(rbind, all_sim_list) # 方法2:用purrr简化代码,没有安装可先运行 install.packages("purrr") # library(purrr) # final_result <- map_dfr(1:sim_times, ~single_run() %>% mutate(sim_id = .x, .before = 1))
优化说明
- 解决了原始代码的潜在问题:原始写法里
rnorm(1,5,10)有概率生成负值,减去负值会让新值大于旧值,破坏严格递减规则,上述代码加了步长校验,保证每一步步长为正,完全满足序列严格递减的要求 - 采用列表预存结果+最后一次性合并的写法,比逐次
bind_rows()/rbind()的效率高10~100倍,跑上万次模拟也不会卡顿 - 输出结果自带轮次、步长标识,后续做统计、画轨迹图直接按
sim_id分组即可,不需要额外整理数据
内容的提问来源于stack exchange,提问作者stats_noob
相关产品推荐
相关产品推荐

