R中依赖于结果的for循环优化?

时间:2012-05-18 15:40:19

标签: r

我知道矢量化以及它如何应用于加速R中的循环,但我无法找到一种方法来使用向量来加速代码,其中每次迭代都依赖于前一次迭代的结果,或者依赖于迭代随机区间计算。

例如:

乔什 - 抱歉。所以,这里有更多细节:

m <- c(1, 1)
w.r <- c(0.33592935393, 0.63825353030, 0.15335253356 )

和rlistl是3个2x2矩阵的列表。所以,为了交谈,

r0 <- matrix(0, 2, 2) 
r1 <- matrix(1, 2, 2)
r2 <- matrix(2, 2, 2)
rlist <- list(r0, r1, r2)

N <- 500
E <- matrix(0, N, 2)

for(i in 1:N) {
    r <- c(c(1:3) %*% rmultinom(1, 1, w.r))
    E[i, ] <- mvrnorm(1, m, rlist[[r]])
}

我尝试在循环外部进行“r&lt; - multinom()”计算,并且rprof显示花费的大部分时间显然是mvnorm。任何人都可以在R中找到一种方法来加速使用向量吗?

这是另一个例子

for(i in 1:N) {
    if(d$V[i, 1] & d$V[i, 2]) QQ <- 1
    else if(! d$V[i, 1] & d$V[i, 2]) QQ <- 2
    else if(! d$V[i, 1] & ! d$V[i, 2]) QQ <- 3
    else if(d$V[i, 1] & ! d$V[i, 2]) QQ <- 4

    U[i, ] <- r1bvtruncnorm(mux=mu.U[i, ]/sd.r[r1], rho=rho, q=QQ)

}

无法想出一种方法可以让它更快地运行。我的一部分问题是我是一名C / C ++程序员,但我一直在努力阅读R,并希望确保我不会错过任何简单的东西。

感谢。

编辑:

贾斯汀:

好的 - 所以我尝试了你的建议,但正如我所担心的那样,rep()的行为并不像我希望的那样。我每次都需要一个单独的随机数,但是使用rep()只调用rmultinom一次并将结果复制100次。

>rep(c(c(1:3) %*% rmultinom(1, 1, ww.r)), 100)
  [1] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
 [38] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
 [75] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2

> rep(c(c(1:3) %*% rmultinom(1, 1, ww.r)), 100)
  [1] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
 [38] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
 [75] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1

1 个答案:

答案 0 :(得分:0)

请参阅Josh对任何我猜错的评论。

但假设你没有留下任何其他内容,w.r是不变的,应该从循环中删除。 m也是不变的。 'r'和rlist [[r]]是随机生成的,但参数不变。那么你正在做的是从相同的参数生成分布N次,对吗?如果是这种情况,那么有比for循环更好的选择。 e.g。

E <- matrix(rep(mvrnorm(1, 
                       m, 
                       rlist[[c(1:3 %*% rmultinom(1, 1, w.r))]]), 
                N),  
            N, 
            2)

它应该给你与第一个for循环相同的结果。

您的第二个示例可以成为一个函数并使用apply。但是,在不知道d对象的实际结构的情况下,很难知道如何最好地接近它。我假设它像data.frames的data.frame或列表的命名列表。其中d$V是一些二维数据结构:

my.fun <- function(vec) {
    if(vec[1] & vec[2]) return(1)
    else if(! vec[1] & vec[2]) return(2)
    else if(! vec[1] & ! vec[2]) return(3)
    else if(vec[1] & ! vec[2]) return(4)
}

QQ <- apply(d$V, 1, my.fun)

根据评论编辑:

r  <- 1:3 %*% rmultinom(N, 1, w.r)
E <- t(sapply(r, function(x) mvrnorm(1, m, rlist[[x]])))

或者在一条混乱的线路上:

t(sapply(1:3 %*% rmultinom(N, 1, w.r), function(x) mvrnorm(1, m, rlist[[x]])))