R语言simmer包:无法将get_mon_resources结果存入变量求助
问题排查与解决方案
我帮你分析下代码里的几个关键问题,以及对应的修复方案:
1. 变量作用域导致无法保留监控数据
你在lapply的匿名函数内部定义了mydata <- get_mon_resources(elevator),这个变量是局部变量,只会存在于当前迭代的函数环境中,循环结束后外部无法获取这些数据。
解决方法:让lapply的每个迭代返回get_mon_resources(elevator)的结果,这样循环结束后可以得到一个包含所有100次仿真资源数据的列表。
2. 未启用属性设置导致日志报错
你注释掉了set_attribute("start_time", function() {now(elevator)}),但后面的log_语句又尝试获取这个属性,这会导致运行时出现"attribute not found"的错误,进而影响整个仿真流程。
解决方法:取消这行代码的注释,同时修正trajectory中函数的写法——在simmer的trajectory函数里,不需要显式传入仿真对象,now()和get_attribute()会自动使用当前的仿真环境:
set_attribute("start_time", function() now()) %>% # ... log_(function() paste("Waited: ", now() - get_attribute("start_time"))) %>%
3. 优化仿真对象的引用方式
在trajectory中直接引用elevator对象可能存在作用域捕获问题,改用无参数的now()和get_attribute()更安全,符合simmer的最佳实践。
修复后的完整代码
library(simmer) SystemTime <- 200 delay <- c(20,40,60,80,100,120,140,160,180,200)/60 set.seed(1234) # 让lapply返回每次仿真的资源监控数据 all_resource_data <- lapply(1:100, function(i) { elevator <- simmer("elevator") worker <- trajectory("elevator service") %>% log_("new worker arrived") %>% set_attribute("start_time", function() now()) %>% # 启用属性设置,去掉显式的elevator引用 seize("elevator", amount = 1) %>% timeout(function() sample(delay, 1)) %>% log_(function() paste("Waited: ", now() - get_attribute("start_time"))) %>% # 去掉显式的elevator引用 release("elevator") elevator %>% add_generator("worker", worker, function() rexp(1, 2)) %>% add_resource("elevator", capacity = 2) %>% run(until = SystemTime) # 返回当前仿真的资源监控数据 get_mon_resources(elevator) }) # 可以将列表合并为一个数据框方便分析(如果需要) combined_data <- do.call(rbind, all_resource_data)
验证修复效果
- 运行上述代码后,
all_resource_data会包含100个数据框,每个对应一次电梯仿真的资源使用情况; combined_data则是合并后的完整数据集,你可以用head(combined_data)查看前几行数据,确认资源监控数据已正确存储。
内容的提问来源于stack exchange,提问作者Dor Aharoni
相关产品推荐
相关产品推荐

