【问题标题】:Repeat R script multiple times多次重复 R 脚本
【发布时间】:2015-11-12 04:26:31
【问题描述】:

我有一个包含数百行的 R 脚本。这个脚本最终给了我一个单一的数字答案。现在我想创建一个置信区间,因此多次运行整个脚本,以便能够计算平均值和标准差。但我不想在整个事情上创建一个“for”循环,因为这变得非常复杂

经过一番研究,我发现了这种方法:

我的最终答案被命名为“结果”,然后在一个新的脚本文件中,

result_list<-lapply(1:10, function(n)source("my_script_file.R"))
result_list

(例如重复10次)

然而最终的结果是这样的,

[[1]]
[[1]]$value
[1] 136.9876

[[1]]$visible
[1] TRUE

[[2]]
[[2]]$value
[1] 138.4969

[[2]]$visible
[1] TRUE

[[3]]
[[3]]$value
[1] 0.2356484

[[3]]$visible
[1] TRUE

. 
.

现在我不知道第二行在每次迭代中意味着什么?以及如何获取值列表,result_list$values 不起作用,同时还忽略了可能是模拟错误的太小值,例如此处的第三个值,无法计算平均值和 sd。

除了这个方法,还有其他方法可以重复这个过程吗?

【问题讨论】:

    标签: r iteration repeat lapply


    【解决方案1】:

    我建议将您的脚本作为一个函数,加载该函数一次,然后使用replicate 而不是lapply(1:n, ...)

    这是一个非常简单的例子:

    假设您正在使用具有以下内容的简单 R 脚本文件:

    ## saved in working directory as "testfun.R"
    myFun <- function(x, y, z) {
      mean(rnorm(x)) + mean(rnorm(y)) + mean(rnorm(z))
    }
    
    myFun(10, 12, 14)
    ## End of "testfun.R" file
    

    现在,比较必须 source 100 次和必须简单地运行函数 100 次的时间:

    fun1 <- function(n = 10) replicate(n, myFun(10, 12, 14))
    fun2 <- function(n = 10) lapply(1:n, function(x) source("testfun.R")$value)
    
    library(microbenchmark)
    microbenchmark(fun1(100), fun2(100), unlist(fun2(100)), times = 1)
    ## Unit: milliseconds
    ##               expr       min        lq      mean    median        uq       max neval
    ##          fun1(100)  3.064384  3.064384  3.064384  3.064384  3.064384  3.064384     1
    ##          fun2(100) 59.635228 59.635228 59.635228 59.635228 59.635228 59.635228     1
    ##  unlist(fun2(100)) 61.349713 61.349713 61.349713 61.349713 61.349713 61.349713     1
    

    我不确定如果更多时间用于处理(而不是读取源文件),从长远来看会有多大的不同,但我仍然会考虑一个函数 + replicate作为更清洁和更易于阅读的替代品。

    【讨论】:

    • 感谢您的建议。但这里的问题是我的 R 脚本中已经有多个循环和函数,因此将所有这些合并到一个新函数中需要进行大量更改和编辑,并使其更加复杂。
    • @mac,我不明白为什么会有问题。只需将整个事物包装在一个函数中即可。它不应该比这更复杂......
    • 嗯,让我试一试。但是整个过程中有很多变量,我需要将它们全部包含在我的新函数中(对吗?)。而且我知道您建议的方法比上面看到的要快得多,但在我的情况下这不是什么大问题。但尽管如此,我还是想尝试一下。我仍处于 R 的学习阶段。再次感谢。欣赏它:)
    • @mac,没有。例如,请参阅我在基准测试步骤中如何编写 fun1()fun2()。我刚刚添加了一个参数,它采用了我想要做的迭代次数。请注意,要使用fun1(),我必须首先获取"testfun.R" 文件。
    【解决方案2】:

    我们可以使用$value 从每次迭代中获取“价值”

     lapply(1:10, function(n)source("my_script_file.R")$value)
    

    由于它是单个元素,因此使用 sapply 获得 vector 输出可能也很有用

     v1 <- sapply(1:10, function(n)source("my_script_file.R")$value)
    

    我们可以为大于特定阈值(例如 0.5)的值设置 vector 的子集,

     v1[v1 > 0.5] 
    

    【讨论】:

      猜你喜欢
      • 2018-04-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-30
      • 2021-10-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多