【问题标题】:Combining lists into a dataframe more efficiently更有效地将列表组合到数据框中
【发布时间】:2018-02-18 21:40:03
【问题描述】:

我正在运行MCMCglmm() 模型的多个链,我正在尝试找到最有效的方法来合成我的输出。

我正在使用mclapply() 运行 4 条链,然后将 4 条链中的每条链与lapply() 组合成一个列表。

这是我清理和组合链的模型和代码。我正在使用这个有用的教程来运行链:https://github.com/tmalsburg/MCMCglmm-intro

型号:

library(parallel)
chains <- mclapply(1:4, function(i) {
  MCMCglmm(outcome ~ 1 + pretest + race + satisfaction*race, data = data,
                                random = ~ provider,
                                prior = prior.1,
                                verbose = TRUE,
                                family = "gaussian",
                                nitt = 10000, 
                                burnin = 5000, 
                                thin = 10)
}, mc.cores=4)

我的清理工作有点笨拙。有没有办法在固定和随机效果上运行lapply 命令(或者我认为需要的是mapply)以将它们组合到同一个列表和后续数据帧中?最后,我希望有一个数据框,这样我就可以添加/减去后验分布并对其进行汇总统计。

fixed <- lapply(chains, function(m) m$Sol) # Sol = fixed effects 
fixed <- do.call(mcmc.list, fixed)
summary(fixed)

random <- lapply(chains, function(m) m$VCV) # VCV = variance 
random <- do.call(mcmc.list, random)
summary(random)

fixed_df <- do.call(rbind, Map(data.frame, fixed))
random_df <- do.call(rbind, Map(data.frame, random))

chains_df <- cbind(fixed_df, random_df)

最终,我希望运行一个 lapply()mapply() 并拥有一个固定的随机列表。我相信我可以使用Map(data.frame, fixed.random) 来创建我的数据框。我对 apply 函数的了解是有限的,所以我希望了解更多并将它(不是双关语)应用到我的数据集。

不幸的是,模型输出 MCMC 对象,所以我无法创建确切的结构。这是我能想到的最好的:

list1 <- list(a = rnorm(100, 0, 1), b = rnorm(100, 0, 1))
list2 <- list(a = rnorm(100, 0, 1), b = rnorm(100, 0, 1))
list3 <- list(a = rnorm(100, 0, 1), b = rnorm(100, 0, 1))
list4 <- list(a = rnorm(100, 0, 1), b = rnorm(100, 0, 1))

list5 <- list(d = rnorm(100, 0, 1), e = rnorm(100, 0, 1))
list6 <- list(d = rnorm(100, 0, 1), e = rnorm(100, 0, 1))
list7 <- list(d = rnorm(100, 0, 1), e = rnorm(100, 0, 1))
list8 <- list(d = rnorm(100, 0, 1), e = rnorm(100, 0, 1))

fixed  <- list(list1, list2, list3, list4)
random <- list(list5, list6, list7, list8)

【问题讨论】:

  • 什么是mcm.list?请提供reproducible example的数据样本。
  • mcmc.list 是一个代表同一链并行运行的函数......我无法创建输出,因为它是一个 MCMC 对象。我可以试试非 MCMC 对象。
  • 基本上是在寻找类似lapply(chains, function(m) c(m$Sol, m$VCV)) 的东西,但这是不对的。
  • 阅读mcmc.list docs,看来处理必须分开。您可以使您的代码干燥以避免重复。
  • 谢谢,冻糕。 DRY-er 是什么意思?

标签: r apply lapply mcmc mapply


【解决方案1】:

下面会做吗?

假设您的four_mcmc"MCMCglmm" 类的模型列表(chain1chain2 等),extract 是您要从链中读取的元素列表(在您的固定("Sol")和随机项("VCV"))。

## The list of mcmcs
four_mcmc <- list(chain1, chain2, chain3, chain4)

## Which elements to extract from the MCMCs
extract <- c("VCV", "Sol")

您可以使用get.element 函数从单个链中提取单个元素列表:

## Extracting some specific elements from a chain
get.elements <- function(extract, mcmc) {
    ## Extracting the element
    mcmc_elements <- sapply(extract, function(extract) mcmc[which(names(mcmc) == extract)])
}

## Extracting the VCV and Sol from one chain
str(get.elements(extract, chain1))

然后您可以简单地将这个函数应用到您的链列表中:

## Applying get.element for each elements to extract on each chain
all_elements <- lapply(four_mcmc, function(mcmc, extract) get.elements(extract, mcmc), extract)

然后,您可以轻松地将每个术语的此表汇总为一个数据框,其中术语为行,链为列

## Fixed terms table
fixed_terms <- as.data.frame(lapply(all_elements, function(X) X[[1]]))
## Random terms table
random_terms <- as.data.frame(lapply(all_elements, function(X) X[[2]]))

此代码是从https://github.com/TGuillerme/mulTree 中的read.mulTree 函数简化而来的。

[编辑] @headpoint 建议简单地使用:

as.data.frame(lapply(chains, function(m) cbind(m$Sol, m$VCV)))

哪个更优雅但可能不太便携。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-04-23
    • 1970-01-01
    • 2017-08-11
    • 2016-11-22
    • 1970-01-01
    • 1970-01-01
    • 2015-10-01
    • 2018-11-19
    相关资源
    最近更新 更多