如何在循环中保存计算Moran指数所用的随机系统发育树?
问题描述
我需要从数据集里随机选取若干系统发育树计算Moran指数,希望能同时得到每轮循环对应的Moran指数结果和所用的系统发育树,明确知道每次计算用的是哪棵树。目前我能获取随机树的Moran指数值,但无法保存每轮选中的树。以下是我写的示例R代码,求解决方法:
library(ape) x <- rmtree(20, 20) names(x) <- paste("t", 1:10, sep = "") var <- as.data.frame(matrix(rnorm(20),nrow=20)) nams <- data.frame(paste0("t",1:20,sep="")) var_list <- cbind(nams,var) colnames(var_list) <- c("names","variable") var_list1 <- var_list$variable names(var_list1) <- c(var_list[,1]) # Loop to select a random tree and run the Moran index tr <- function(x, var_list1){ resulist <- as.list(1:15) # treelist <- as.list(as.phylo(x[[i]])) #### not working for(i in 1:15){ tutreer <- sample(x,size=1)[[1]] inr <- 1/cophenetic(tutreer) diag(inr) <- 0 mran <- Moran.I(var_list1,inr,scaled = TRUE) mran resulist[[i]] <- list(obs=mran$observed,expect=mran$expected, sd=mran$sd,pval=mran$p.value) # treelist[[i]] <- list(tutreer) #### Here, not working } return(resulist) # return(treelist) } tr(x,var_list1)
解决方法
核心问题是原代码尝试分开存储指数结果和树,但函数只能返回一个对象,且树的列表初始化方式错误。可以让每轮循环的结果同时包含Moran指数信息和对应的系统发育树,把两者打包到同一个列表元素里。
修正后的代码:
library(ape) # 生成示例数据(修正原代码树命名不匹配的问题) x <- rmtree(20, 20) names(x) <- paste("t", 1:20, sep = "") var <- as.data.frame(matrix(rnorm(20), nrow=20)) nams <- data.frame(paste0("t",1:20,sep="")) var_list <- cbind(nams, var) colnames(var_list) <- c("names","variable") var_list1 <- var_list$variable names(var_list1) <- var_list[,1] # 改写函数,同时保存Moran结果和对应的树 tr <- function(x, var_list1){ # 初始化结果列表,每个元素将包含指数结果、树和树的名称 result_tree_list <- vector("list", length = 15) for(i in 1:15){ # 随机选一棵树,同时记录它的原始名称(方便追踪) selected_idx <- sample(length(x), size=1) tutreer <- x[[selected_idx]] tree_name <- names(x)[selected_idx] # 计算Moran指数 inr <- 1/cophenetic(tutreer) diag(inr) <- 0 mran <- Moran.I(var_list1, inr, scaled = TRUE) # 将所有相关信息打包到同一个列表元素 result_tree_list[[i]] <- list( tree_name = tree_name, phylogenetic_tree = tutreer, moran_results = list( observed = mran$observed, expected = mran$expected, sd = mran$sd, p_value = mran$p.value ) ) } return(result_tree_list) } # 运行函数 output <- tr(x, var_list1) # 示例:查看第1轮的结果 output[[1]]$tree_name # 查看用了哪棵树的名称 output[[1]]$phylogenetic_tree # 查看选中的系统发育树结构 output[[1]]$moran_results # 查看对应的Moran指数结果
修改说明
- 修正原代码的命名错误:原代码生成20棵树但只命名到
t10,改为匹配20棵树的命名t1到t20,方便追踪原始数据集里的树。 - 规范列表初始化:用
vector("list", length = 15)创建指定长度的空列表,避免原代码的冗余初始化方式。 - 增加树的追踪信息:随机选树时记录索引和原始名称,后续可以直接对应到原始数据集。
- 打包完整信息:每轮循环将树名称、系统发育树对象、Moran指数结果合并到同一个列表元素,返回的结果列表能直接对应每轮的计算和所用的树。
内容的提问来源于stack exchange,提问作者mmmap
相关产品推荐
相关产品推荐

