Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
循环的顺序对R中的速度有影响吗_R - Fatal编程技术网

循环的顺序对R中的速度有影响吗

循环的顺序对R中的速度有影响吗,r,R,我有一个问题,我想运行一个模拟研究,其中模拟取决于两个变量x和yx和y是我想在模拟研究中评估的潜在值向量(如此不同的组合)。此外,对于x和y的每个组合,我需要多个复制(因为其中有一个随机项,x和y的每次运行都会有所不同) 为了举例说明我正在处理的问题,我有以下简化示例: x = 1:10 y = 11:20 iterations = 2000 iter = 1 solution = array(NA,c(length(x),3,iterations)) for(i in x){ fo

我有一个问题,我想运行一个模拟研究,其中模拟取决于两个变量
x
y
x
y
是我想在模拟研究中评估的潜在值向量(如此不同的组合)。此外,对于
x
y
的每个组合,我需要多个复制(因为其中有一个随机项,
x
y
的每次运行都会有所不同)

为了举例说明我正在处理的问题,我有以下简化示例:

x = 1:10
y = 11:20

iterations = 2000
iter = 1

solution = array(NA,c(length(x),3,iterations))
for(i in x){
    for(j in y){
        for(k in 1:iterations){ 
            z = rnorm(3) + c(i,j,1) 
            solution[i,,k] = z
        }
    }
}
然而,在我的实际问题中,在for循环中计算的代码要少得多。但是,我的输入结构与输出结构相同

因此,我想知道的是,使用上面的例子,按照这个顺序设置循环是最有效的还是最好让
k in 1:iterations
成为最外层的循环,并尝试在该1循环中使用某种
outer()
命令,因为我将评估函数(
z
)在网格上
x
y

另外,我对完全不同的设置和设计非常开放。在一天结束时,我希望能够获得一个基于
x
y
并在所有迭代中求平均值的解决方案,即
应用(解决方案,c(1,2),平均值)


编辑: 正如向我建议的,下面是我正在使用的实际代码

library(survival)

iter = 2000
n = 120
base = 2
hr = 0.5
m.x = 3
m.y = m.x/hr

ANS = NULL
for (vecX in c(0.3, 0.5, 0.6, 0.7)){
out = NULL

    for (vecY in c(0, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 0.95)){
        m.x.p = m.x/vecX
        m.y.p = m.y/vecX
        m.x.n = m.x
        m.y.n = m.y
        
        n.t = round(n*base/(base+1))
        n.c = n - n.t
        
        for (ii in 1:iter){
            n.t.p = rbinom(1, n.t, vecY)
            n.t.n = n.t - n.t.p
            n.c.p = rbinom(1, n.c, vecY)
            n.c.n = n.c - n.c.p
            
            S = c(rexp(n.t.p, log(2)/m.y.p), rexp(n.t.n, log(2)/m.y.n), rexp(n.c.p, log(2)/m.x.p), rexp(n.c.n, log(2)/m.x.n))
            
            data1 = data.frame(Group = c(rep("T", n.t), rep("C", n.c)), dx = c(rep("P", n.t.p), rep("N", n.t.n), rep("P", n.c.p), rep("N", n.c.n)), S)
            
            fit = survfit(Surv(data1$S)~data1$Group)
            coxfit = coxph(Surv(data1$S)~data1$Group)
            
            HR = exp(coxfit$coefficients)
            p.val=summary(coxfit)$logtest["pvalue"]
            
            out = rbind(out, c(vecX, vecY, n.t.p, n.t.n, n.c.p, n.c.n, HR, p.val))
        }
        
    }
    colnames(out) = c("vecX", "vecY", "n.t.p", "n.t.n", "n.c.p", "n.c.n", "HR", "p.val")
    
    ans = as.data.frame(out)
ANS = rbind(ANS, ans)

}

是的,我相信理论上它应该会有所不同(见下面的例子)

R像Fortran一样使用列主顺序(和C不同),所以为了最小化缓存未命中,您可能希望向下遍历列。因此,对于填充矩阵,最佳方法是外循环有我们的列索引的方法

对于n维数组,你也应该记住这一点。在
n=3
的情况下,我想这意味着层是最外层的循环,然后是列,然后是行。不过,我可能是搞错了

我用
5000
by
5000
矩阵运行了这个快速示例。我们看到了大约50秒的差异,
fill_matrix2()
更快

    n <- 5000
    A <- matrix(NA, n, n)
    B <- matrix(NA, n, n)

    fill_matrix1 <- function(X, val) {
        for (i in 1:nrow(X)) {
            for (j in 1:ncol(X)) {
                X[i, j] <- val
            }
        }
        return(X)
    }

    fill_matrix2 <- function(X, val) {
        for (j in 1:ncol(X)) {
            for (i in 1:nrow(X)) {
                X[i, j] <- val
            }
        }
        return(X)
    }

    system.time(fill_matrix1(A, 0))
    system.time(fill_matrix2(B, 0))

n这里循环的顺序实际上是不相关的。如果您分析代码(请参阅
帮助(“Rprof”)
),您将看到CPU时间花费在
survfit
coxph
等函数上。当然,在成长中,你应该避免。预先分配
到它的最终大小,并填充它,而不是增加它。

我想这实际上取决于你在循环中拥有什么,以及你是否可以矢量化它。在您的示例中,您可以通过
z@nicola完全删除
k
循环。上面的示例完全是虚构的。它更能说明我的结构以及输入和输出。是的,我知道这个例子是虚构的。我的观点是你必须尝试矢量化。根据我的经验,在很多情况下,人们试图通过使用
lappy
来节省时间,而不是
sapply
或反向循环,在这些情况下,矢量化是可用的,程序员没有意识到这一点。与成功实现矢量化相比,这种优化通常可以忽略不计。所以,如果你真的想优化,试着用一种你可以矢量化的方式重新思考你的代码。如果不能,请不要浪费时间考虑循环顺序。@nicole,在这里发布我的实际代码供人们评论合适吗?我不想因为发布“这是我的代码,请快一点”而被标记@SymbolX我将用我的实际代码更新我的问题。对于较小的“n”,两个函数之间的计时似乎没有太大差异,对于较大的函数,我无法获得一致的行为。也许是因为
[当然,我同意我应该预先分配大小。我还可以做些什么来优化代码以更快地运行?正如我指出的:您的第一步应该是分析您的代码。