R函数中的全局赋值运算符-有什么更好的替代方法?

问题描述

我在程序包中有一个函数(主要供我自己使用,将来可能会共享)。我试图用lapply替换一个慢速的for循环,以便以后可以并行化它。因此,我发现即使没有并行处理也要快得多的一种选择是使用全局赋值运算符。但是,我对此感到焦虑,因为这似乎不被接受,而且我不习惯思考环境,因此担心副作用:

这是一个简单的代表:



n <- 2
nx <- 40
v <- 5
d <- 3

array4d <- array(rep(0,n * nx * v * d),dim = c(n,nx,v,d) )
array4d2 <- array4d

# Make some data to enter into the array - in real problem a function gens this data depending on input vars

set.seed(4)
dummy_output <- lapply(1:v,function(i) runif(n*nx*d))

microbenchmark::microbenchmark( {
    for(i in 1:v){
        array4d[,i,] <- dummy_output[[i]]
    }
},{
    lapply(1: v,function(i) {
        array4d2[,] <<- dummy_output[[i]]
    })
})

Unit: microseconds
                                                                                     expr      min        lq
             {     for (i in 1:v) {         array4d[,] <- dummy_output[[i]]     } } 1183.504 1273.6205
 {     lapply(1:v,function(i) {         array4d2[,] <<- dummy_output[[i]]     }) }   13.257   16.1715
       mean    median       uq      max neval cld
 1488.26909 1411.4565 1515.762 3535.974   100   b
   33.56976   18.1445   21.150 1525.608   100  a 
> 
> identical(array4d,array4d2)
[1] TRUE

所有这些都会在其父函数多次调用函数中发生。

所以这(很多!)更快。 但是我的问题是

  1. 这样做安全吗?
  2. 是否有不使用<<-的类似快速替代方案?

解决方法

使变化的尺寸成为最后一个尺寸。微基准测试表明其性能与使用全局变量的性能在统计上没有差异。如果重要的是将尺寸作为第三个维度,请在之后使用/* --- IMPORT --- */ @import url("https://use.typekit.net/ptx4dws.css"); /* --- MOBILE ---*/ /* Global */ h1 { font-family: proxima-nova,sans-serif; font-weight: 800; font-style: normal; text-transform: uppercase; font-size: 4rem; font-weight: 800; } h2 { font-family: proxima-nova,sans-serif; font-weight: 800; font-style: normal; text-transform: uppercase; font-size: 3rem; font-weight: 800; } .newLine { display: block; font-size: 2.2rem; font-weight: 500; } p { font-family: proxima-nova,sans-serif; font-weight: 500; font-style: normal; } a { text-decoration: none; color: black; } .break { width: 100vw; position: relative; left: 50%; right: 50%; margin-left: -50vw; margin-right: -50vw; } .centerMobile { display: block; margin-left: auto; margin-right: auto; } /* NavBar */ .topNav { background-color: rgb(232,19,35); } .navLogo { height: 80px; margin: 10px auto 10px auto; align-content: center; } .menuList { list-style: none; } .topNav li { padding: 5px 5px 5px 5px; } .topNav a { color: white; font-size: 1.7em; } .topNav a:hover { text-decoration: none; font-weight: 600; } /* Hero */ .hero { padding: 25vw 5vw 25vw 5vw; background-image: url(/assets/heroBG.png); background-position: center; background-size: cover; } .hero h1 { text-transform: uppercase; font-size: 4rem; font-weight: 800; } .hero .newLine { display: block; font-size: 2.2rem; font-weight: 500; } /* Horizontal Layout*/ .horizontalLayout .item { padding: 10px 10px 10px 10px; }

aperm(x,c(1,2,4,3))