如何创建一个循环来计算系统发育信号并将结果存储在 R 中的多个向量中

How to create a loop to calculate phylogenetic signal and store results in several vectors in R

我需要计算 100 多个变量的系统发育信号并存储结果 'K stats' 和 'p-value' 以创建一个数据框,其中我有 3 列指定变量名称、K-stats 和p值。我知道如何为 1 个变量执行此操作,但我只是不想重复该过程 100 次。另外,我认为循环可能是避免问题的更有效方法。

所以这就是我认为应该的方式,我只是不知道如何实现它。首先,一些虚拟数据:

require(geiger)
require(phytools)
tree<-sim.bdtree(b=0.1,d=0,stop="taxa",n=50,extinct=FALSE)
trait<-matrix(rTraitCont(compute.brlen(tree,power=5),model="BM"),50,10)
trait <- as.data.frame(trait)
rownames(trait)<-tree$tip.label

# This is how it is done for 1 variable at the time: 

trait.1 <- setNames(trait$V1, rownames(trait))
trait.1.test <- phylosig(tree, trait.1, method = 'K', test = T)
trait.1.test$K
trait.1.test$P

那我觉得应该是这样结构的for循环:

# list1 <- list()
# List.Of.Kvalues <- list()
# List.Of.Pvalues <- list()


#For loop {
  # First I need a list that containes each column with the tree tip names or row names of the original data frame (this two are equal)
    # list1 <- list(setName(trait[col1], rownames(trait)))
  #Second I will use each list inside list1 to calculate the phylogenetic signal and stored the K value and another with p-values
    # List.Of.Kvalues <- phylosig(tree, list1[], method = K, test = T)$K
    # List.Of.Pvalues <- phylosig(tree, list1[], method = K, test = T)$P
# }

#Finally create the dataframe
# df <- rbind(colnames(trait),List.Of.Kvalues, List.Of.Pvalues)
 

我对如何预制循环的知识很基础,希望有人能帮助我了解如何构建这种循环。谢谢!!

使用 base R,您可以使用 lapply 将测试应用于每一列

cbind(do.call("rbind.data.frame", lapply(trait, function(x) {
  data <- setNames(x, rownames(trait))
  test <- phylosig(tree, data, method = 'K', test = TRUE)
  list(K = test$K, P = test$P)
})), trait=names(trait))

也许 dplyrbind_rows

更漂亮
library(dplyr)
Map(function(x) {
    data <- setNames(x, rownames(trait))
    test <- phylosig(tree, data, method = 'K', test = TRUE)
    list(K = test$K, P = test$P)
  }, trait) %>% 
  dplyr::bind_rows(, .id="trait")

请注意,对于您的示例,此 returns 每行的值都相同,因为 trait 的列看起来完全相同。

使用 for 循环:

library(geiger)
library(phytools)
#Initializtion part
tree<-sim.bdtree(b=0.1,d=0,stop="taxa",n=50,extinct=FALSE)
trait<-matrix(rTraitCont(compute.brlen(tree,power=5),model="BM"),50,10)
trait <- as.data.frame(trait)
rownames(trait)<-tree$tip.label
n <- ncol(trait)
Kvalues <- numeric(n)
Pvalues <- numeric(n)

#Loop over each column and get K and p values
for(i in seq_len(n)) {
  trait.1 <- setNames(trait[[i]], rownames(trait))
  trait.1.test <- phylosig(tree, trait.1, method = 'K', test = T)
  Kvalues[i] <- trait.1.test$K
  Pvalues[i] <- trait.1.test$P
}

创建一个组合所有值的数据框

out <- data.frame(colname = names(trait), K = Kvalues, P = Pvalues)