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

循环无法存储函数输出:遗传漂变模拟函数多参数循环失败求助

解决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

为什么之前的循环会失败?

大概率是这两个原因:

  1. 存储结构不合适:用了固定维度的矩阵/数据框,但不同t对应的输出列数不同,无法填充;
  2. 列表索引错误:用了单括号[i]给列表赋值,这会把结果存成子列表而不是直接存储矩阵,导致后续无法正常访问数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 11:32:16