如何使用mapply在R中的两个列表的列上执行函数?

问题描述

我正在尝试计算 R 中两个列表的第 n 个元素的种群遗传统计量(平均 FST)。此统计量需要计算种群方差,而 R 没有针对该种群的本机函数。我不知道如何将适用于数据框(2 行)的代码转换为适用于 2 个列表的代码

以下是适用于两行数据框的代码示例:

#Generate dataframe data
popa <- abs(rnorm(10,mean = 0,sd = 0.5))
popb <- 1-abs(rnorm(10,sd = 0.5))
totalpop <- rbind(popa,popb)

#Make population variance function
pvar <- function(x) {
  sum((x - mean(x))**2) / length(x)
}

#Calculate statistic on each column,and take the global mean
MeanFST <- mean(apply(totalpop,2,pvar)/((apply(totalpop,mean))*(1-(apply(totalpop,mean)))))

但我不知道如何将这段代码转换为对列表进行操作的代码

#Generate lists data
listA <- list()
listB <- list()
for(i in 1:30){
  listA[[i]] <- abs(rnorm(10,sd = 0.5))
  listB[[i]] <- 1 - abs(rnorm(10,sd = 0.5))
}

我试过像这样使用 Map,

results <- Map(function(X,Y) {
  mean(apply(totalpop,mean)))))
},X = listA,Y = listB)

但显然这行不通,因为它需要“totalpop”,当我在两个列表上计算统计数据时(仅当我组合两个数据框时)它不存在。

如何在两个列表上进行 MeanFST 计算?

解决方法

我们可以在按列拆分数据后使用lapply/sapply

 mean(sapply(asplit(totalpop,2),function(x) pvar(x)/(mean(x) * (1 - mean(x)))))

或者使用 apply 和一个 lambda 函数

mean(apply(totalpop,2,function(x) pvar(x)/(mean(x) * (1 - mean(x)))))

Map 部分,我们可能需要 cbind 两个 list 元素并使用与 applysapply 相同的代码

unlist(Map(function(u,v) mean(apply(cbind(u,v),function(x) pvar(x)/(mean(x) * (1 - mean(x))))),listA,listB))