【问题标题】:R How to return several data frames as output from foreach loopsR如何返回几个数据帧作为foreach循环的输出
【发布时间】:2018-06-19 09:39:54
【问题描述】:

我正在尝试并行化我正在使用 foreach 运行的以下模拟,但我正在努力将结果组合成一个有意义的数据结构。

我想做什么(或者没有并行化我是怎么做的): 1. 创建 4 个数据框来存储我的结果: 2. 运行我的模拟循环(例如 100 次),在每个循环中,我将结果存储到我的 4 个数据帧的相应行中。

示例代码:

sim_n = 10

sim_power = as.data.frame(matrix(nrow=sim_n, ncol=8))
sim_rank  = as.data.frame(matrix(nrow=sim_n, ncol=8))
sim_mean  = as.data.frame(matrix(nrow=sim_n, ncol=8))
sim_base  = as.data.frame(matrix(nrow=sim_n, ncol=8))

for (i in 1:sim_n)
{
 # Here I'm doing sth. different in reality, so take this just as an example
 sim_power[i,] = runif(8, 1, 10)
 sim_rank[i,] = runif(8, 1, 10)
 sim_mean[i,] = runif(8, 1, 10)
 sim_base[i,] = runif(8, 1, 10)
}

完成循环后,我有 4 个不错的数据帧,一切都很好。

现在尝试使用 foreach 执行此操作,我不确定如何设置。我基本上做了或多或少相同的事情,只是将循环更改为:

test = foreach (i =1:sim_n) %dopar%
{
 # Here I'm doing sth. different in reality, so take this just as an example
 sim_power[i,] = runif(8, 1, 10)
 sim_rank[i,] = runif(8, 1, 10)
 sim_mean[i,] = runif(8, 1, 10)
 sim_base[i,] = runif(8, 1, 10)
}

但这显然行不通。我google了一下,发现我可能必须创建自己的输出函数,但我真的不知道该怎么做。

注意:在 foreach 循环之前,我添加了所有相关的并行化初始化,这样可以正常工作。

更新

如果我执行以下操作,我相信我会以列表列表的形式获得结果,但话又说回来,我不确定如何重组它以获得 4 个数据帧。

test = foreach (i =1:sim_n) %dopar%
{
 # Here I'm doing sth. different in reality, so take this just as an example
 sim_power = runif(8, 1, 10)
 sim_rank = runif(8, 1, 10)
 sim_mean = runif(8, 1, 10)
 sim_base = runif(8, 1, 10)

 return(list(sim_power, sim_rank, sim_mean, sim_base))
}

【问题讨论】:

    标签: r dataframe foreach return


    【解决方案1】:

    使用列表是个好主意。你也可以使用parLapply 直接给你一个列表。您可以执行以下操作,并采用您已经完成的操作:

    test = foreach (i =1:sim_n) &dopar%
    {
     # Here I'm doing sth. different in reality, so take this just as an example
     sim_power = runif(8, 1, 10)
     sim_rank = runif(8, 1, 10)
     sim_mean = runif(8, 1, 10)
     sim_base = runif(8, 1, 10)
    
     return(list(sim_power, sim_rank, sim_mean, sim_base))
    }
    
    library(data.table)
    
    sim_power <- rbindlist(lapply(test,function(x){x[[1]]}))
    sim_rank <- rbindlist(lapply(test,function(x){x[[2]]}))
    sim_mean <- rbindlist(lapply(test,function(x){x[[3]]}))
    sim_base <- rbindlist(lapply(test,function(x){x[[4]]}))
    

    【讨论】:

    • 感谢您的帮助。不幸的是,您的代码给了我以下错误: rbindlist(lapply(test, function(x) { : Item 1 of list input is not a data.frame, data.table or list
    【解决方案2】:

    在丹尼斯的帮助下,并进一步搜索了我得到的错误,我想我找到了解决方案。不确定这是否是最优雅或最快的方式,但它似乎有效:

    test = foreach (i =1:sim_n) %dopar%
    {
     # Here I'm doing sth. different in reality, so take this just as an example
     sim_power = runif(8, 1, 10)
     sim_rank = runif(8, 1, 10)
     sim_mean = runif(8, 1, 10)
     sim_base = runif(8, 1, 10)
    
     return(list(sim_power, sim_rank, sim_mean, sim_base))
    }
    
    sim_power = as.data.frame(do.call(rbind,lapply(test,function(x){x[[1]]})))
    sim_rank  = as.data.frame(do.call(rbind,lapply(test,function(x){x[[2]]})))
    sim_mean  = as.data.frame(do.call(rbind,lapply(test,function(x){x[[3]]})))
    sim_base  = as.data.frame(do.call(rbind,lapply(test,function(x){x[[4]]})))
    

    【讨论】:

      猜你喜欢
      • 2020-05-24
      • 2021-09-23
      • 1970-01-01
      • 2020-03-25
      • 1970-01-01
      • 2018-10-17
      • 2013-07-12
      • 2019-10-17
      • 2016-04-29
      相关资源
      最近更新 更多