2014-11-29 6 views
0

소위 순위 통계의 이중 합계를 계산하는 R 코드를 작성했습니다.R : 트리플 루프를 '벡터화'

최소 1000 번 계산을 반복해야하지만 내부에 3 개의 루프가 있으면 한 번만 수행하는 데 꽤 오랜 시간이 걸립니다. 여기

내 코드입니다 :

#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 
} 

내가 R의 크기 s는 동일 (도 않을 수 있기 때문에 다음 첫 번째 기능이 실패 sapply 사용하여 내 기능을 변환 및 적용되지만 시도해야 길이의 r, s는 X (또는 Y)의 길이와 같음).

루프를 없애기 위해 4 개의 벡터를 사용하여 행렬을 생성하는 함수 L을 만드는 방법이 있습니까?

미리 감사드립니다.

// 편집 :

내가 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) 
} 

하지만 그것도 느린 것 같다. (.) :

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) 

나는이 빨리 될 것입니다 확신 아니에요 당신이 rs의 값을 변화시키는 L의 모든 값을 생성 할 경우

+0

속도가'L 사용^2' 대신 할 배 L 함수를 호출하기보다는 (R [J]를, R, S [K] S) k], R, S) * L (r [j], s [k], R, S)'. 또한 연결하는 것보다 위치에 할당하는 벡터를 predimension하는 것이 더 빠릅니다. –

+0

글쎄, 참으로 - 도움이 곱셈 대신에^2를 사용하면, 지금은 거의 2 배 빨라진다. 고마워. 두 함수의 누적 합계를 연결로 대체하여 ca를 저장했습니다. 0.1 초. 그래도 루프를 생략하는 방법이 있는지 궁금해합니다 (실제로는 시간이 덜 필요함). – xpenguinx

+0

사전 치수에 대한 제안 사항을 이해하지 못했는지 확인하십시오. 자신이 한 일을 보여주기 위해 코드를 편집해야합니다. –

답변

1

, 루프없는 방법 일 수 있습니다 . R에서 루프가 비효율적이라는 널리 퍼진 오류 개념이 있습니다. 효율성 향상의 대부분은 내부 기능을 단순화하여 이루어집니다. (R [J] 'L를들 [:

> 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 
아마
+0

실수가 없습니까? rs $ qrs <- L (r [j], s [k], R, S)^2 ? expand.grid를 함수와 함께 사용하는 방법을 잘 모릅니다.하지만 루프가 없으면 더 이상 k 나 j가 없습니다. 그렇습니까? 어쨌든 이러한 L 사용은 "개체 'j'을 (를) 찾을 수 없습니다". – xpenguinx

+0

오른쪽. 'with (rs,)' –

+0

을 포함시켜야하고 색인을 가져와야합니다. –