简体   繁体   English

R:“向量化”三重循环

[英]R: 'vectorizing' a triple loop

I've written a piece of code in R that computes a double sum of the so called rank statistics. 我已经在R中编写了一段代码,计算所谓的秩统计的两倍。

I need to repeat the computation of Q minimum 1000 times but with 3 loops inside, it takes a quite long time to do it just once. 我需要重复最少Q次计算1000次,但是内部有3个循环,一次只需要很长时间。

Here is my code: 这是我的代码:

#u, a - real numbers
l <- function(u, a) {
  -sqrt((1-a)/a)*I(u>=0 & u<a) + sqrt(a/(1-a))*I(u>=a & u<=1)
}


# r,s - real number, R,S - vectors of real numbers (equal lengths)
L<-function(r, s, R, S) {
  n<-length(R)
  x<-0
  for (i in 1:n) {
    x<-x+l(R[i]/(n+1),r) * l(S[i]/(n+1),s)
  }
  1/sqrt(n)*x
}

# r, s, X, Y - vectors of real numbers; X and Y must be equally long
Q<-function(r,s,X,Y) {
  n<-length(X)
  R<-rank(X)
  S<-rank(Y)
  q<-0
  for (j in 1:length(r)) {
    for (k in 1:length(s)) {
      q<-q+L(r[j],s[k],R,S)^2

    }
  } 
  q
}

I tried to transform my functions using sapply and apply, but then the first function failed because the sizes of r and s may not be equal (nor should the lengths of r, s be equal to the length of X (or Y)). 我尝试使用sapply和apply变换函数,但随后第一个函数失败,因为r和s的大小可能不相等(r,s的长度也不应等于X(或Y)的长度)。

Is there any way to produce a function L which takes 4 vectors and produces a matrix, so that I get rid of the loops? 有没有办法产生一个函数L,该函数需要4个向量并产生一个矩阵,所以我摆脱了循环?

Thanks in advance! 提前致谢!

//Edit: //编辑:

I've written an alternative function using mapply: 我已经使用mapply编写了一个替代函数:

Q1<-function(r,s,X,Y) {
  n<-length(X)
  R<-rank(X)
  S<-rank(Y)
  rs <- expand.grid(r,s)
  q<-do.call(mapply, c(function(r,s) L(r,s,R=R,S=S)^2, unname(rs)))
  sum(q)
}

but it seems to be even slower. 但它似乎更慢。

If you want to generate all of the values of L(.) for varying values of r and s , a loop-less method might be: 如果要为rs不同值生成L(。)的所有值, r环方法可能是:

  rs <- expand.grid(r=r,s=s); rm(r); rm(s)
  #edit
  rs$qrs <- with(rs, L(r, s, R, S)^2 )
  q <- sum(rs$qrs)

I'm not convinced this will be faster. 我不相信这会更快。 There is a widespread but erroneous notion that loops in R are inefficient. 有一个普遍但错误的概念,即R中的循环效率低下。 Most of the gains in efficiency will come from simplifying the inner functions. 效率的大部分收益将来自简化内部功能。

    >  set.seed(123)
>    r <- runif(4)
>    s <- runif(3)
>    rs <- expand.grid(r=r,s=s)
> rs
           r         s
1  0.2875775 0.9404673
2  0.7883051 0.9404673
3  0.4089769 0.9404673
4  0.8830174 0.9404673
5  0.2875775 0.0455565
6  0.7883051 0.0455565
7  0.4089769 0.0455565
8  0.8830174 0.0455565
9  0.2875775 0.5281055
10 0.7883051 0.5281055
11 0.4089769 0.5281055
12 0.8830174 0.5281055
> rs$qrs <- with(rs, L(r, s, 1:10, 1:10)^2 )
>   q <- sum(rs$qrs)
> q
[1] 14.39009
> rs
           r         s          qrs
1  0.2875775 0.9404673 0.0004767998
2  0.7883051 0.9404673 0.0003911883
3  0.4089769 0.9404673 6.6571168565
4  0.8830174 0.9404673 0.0017673788
5  0.2875775 0.0455565 0.0004767998
6  0.7883051 0.0455565 0.0003911883
7  0.4089769 0.0455565 6.6571168565
8  0.8830174 0.0455565 0.0017673788
9  0.2875775 0.5281055 0.0004767998
10 0.7883051 0.5281055 0.0003911883
11 0.4089769 0.5281055 6.6571168565
12 0.8830174 0.5281055 0.0017673788

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM