如何创建一个循环来计算系统发育信号并将结果存储在 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))
也许 dplyr
的 bind_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)
我需要计算 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))
也许 dplyr
的 bind_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)