循环无法存储函数输出:遗传漂变模拟函数多参数循环失败求助
解决wright.fisher函数循环调用的存储问题
我明白你遇到的问题了——当循环调用这个遗传漂变模拟函数时,尤其是改变世代数t的时候,没法把每次的结果存下来对吧?这大概率是因为你用了不合适的存储结构(比如固定维度的矩阵),而不同t对应的输出矩阵列数不一样,导致无法填充。下面给你几个实用的解决方案:
先明确函数输出结构
先确认下你的wright.fisher函数返回值:调用后会得到一个nsim行、t列的矩阵,每一行代表一次模拟的世代等位基因频率变化。比如t=10、nsim=5时,输出是5行10列的矩阵。
方案1:针对单一参数(比如t)循环存储
如果只是想对t的多个取值循环,用列表来存储结果最合适——列表可以容纳不同维度的对象,完美适配不同t对应的输出。
# 先保留你的原函数 wright.fisher<-function(p,Ne,nsim,t){ N <-Ne/2 NA1 <- 2*N*p NA2 <- 2*N*(1-p) k <- matrix(0, nrow = max(2, t), ncol = nsim) k[1,] <- rep(NA1, nsim) for (j in 1:nsim) { for (i in 2:t) { k[i, j] <- rbinom(1, 2*N, prob = k[i-1, j] / (2*N)) } } k <- as.matrix(k/(2*N)) t(k) } # 定义要测试的t值 t_candidates <- c(5, 10, 15, 20) # 初始化空列表,长度等于t的候选值数量 t_results <- vector("list", length = length(t_candidates)) # 给列表元素命名,方便后续查找 names(t_results) <- paste0("generations_", t_candidates) # 循环调用函数并存储结果 for (i in seq_along(t_candidates)) { current_t <- t_candidates[i] # 注意用双括号[[i]]给列表赋值,单括号[i]会存成子列表 t_results[[i]] <- wright.fisher(p=0.5, Ne=100, nsim=10, t=current_t) } # 查看其中一组结果,比如t=10的模拟数据 t_results$generations_10
如果你觉得for循环麻烦,也可以用lapply简化代码,更符合R的风格:
t_results_lapply <- lapply(t_candidates, function(t_val) { wright.fisher(p=0.5, Ne=100, nsim=10, t=t_val) }) names(t_results_lapply) <- paste0("generations_", t_candidates)
方案2:针对多参数组合循环存储
如果需要同时测试p、Ne、t等多个参数的不同取值,可以先用expand.grid生成所有参数组合,再循环遍历:
# 定义各参数的候选值 p_candidates <- c(0.2, 0.5, 0.8) Ne_candidates <- c(50, 100, 200) t_candidates <- c(10, 20) # 生成所有参数组合的数据集 param_grid <- expand.grid(p=p_candidates, Ne=Ne_candidates, t=t_candidates) # 初始化结果列表 all_results <- vector("list", nrow(param_grid)) # 循环每个参数组合 for (i in 1:nrow(param_grid)) { current_params <- param_grid[i, ] # 调用函数并存储 all_results[[i]] <- wright.fisher( p=current_params$p, Ne=current_params$Ne, nsim=10, t=current_params$t ) # 给列表元素命名,明确参数组合 names(all_results)[i] <- paste0( "p_", current_params$p, "_Ne_", current_params$Ne, "_t_", current_params$t ) } # 查看某一组特定参数的结果 all_results$p_0.5_Ne_100_t_20
为什么之前的循环会失败?
大概率是这两个原因:
- 存储结构不合适:用了固定维度的矩阵/数据框,但不同
t对应的输出列数不同,无法填充; - 列表索引错误:用了单括号
[i]给列表赋值,这会把结果存成子列表而不是直接存储矩阵,导致后续无法正常访问数据。
内容的提问来源于stack exchange,提问作者MolEcologist29
相关产品推荐
相关产品推荐

