2013-03-04 2 views
1

저는 R에 익숙하지 않고 특히 느린 중첩 루프를 벡터화하는 데 어려움이 있습니다. 루프는 중심 목록 (구조에 저장된 벡터)을 통과하여이 벡터와 아래의 x 배열의 행 사이의 거리를 찾습니다. 나는 이것이 속도를 위해 벡터화 될 필요가 있다는 것을 알고 있지만, 적절한 기능을 알아 내지 못하거나 apply을 사용한다.느린 중첩 루프 있음 R

clusterCenters <- matrix(runif(10000),nrow=100) 
clusterMembers <- matrix(runif(400000),nrow=4000) 

features <- matrix(0,(dim(clusterMembers)[1]),(dim(clusterCenters)[1])) 

for(c in 1:dim(clusterCenters)[1]){ 
    center <- clusterCenters[c,] 
    for(v in 1:(dim(clusterMembers)[1])){ 
    vector <- clusterMembers[v,] 
    features[v,c] <- sqrt(sum((center - vector)^2)) 
    } 
} 

어떤 도움을 주셔서 감사합니다.

+2

[재현 가능한 예] (http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example)를 제공해주십시오. 그렇게 했더라도 코드에서 구문 오류를 발견했을 것입니다. –

+1

(-1) 재현 가능한 예를 제공하면 기꺼이 찬성표를 던질 것입니다. 예를 들어, 35 개의 질문 이후에 기대되는 것입니다. – Arun

+0

@Arun, 사과드립니다. 나는 더 잘 알고 부주의했다. 실제 문제와 관련된 차원이 훨씬 더 크지 만 문제를 보여주는 재현 가능한 예제를 생성했습니다. – Sevenless

답변

2

R의 재활용 규칙을 활용하면 좀 더 빨리 처리 할 수 ​​있습니다. 당신은 R이 열을 주요 순서로 저장한다는 사실을 알아야하고 이에 대해 설명해야합니다. clusterMembers을 바꾸면 center 벡터가 t(clusterMembers) 열을 따라 재활용됩니다.

set.seed(21) 
clusterCenters <- matrix(runif(10000),nrow=100) 
clusterMembers <- matrix(runif(400000),nrow=4000) 
# your original code in function form 
seven <- function() { 
    features <- matrix(0,(dim(clusterMembers)[1]),(dim(clusterCenters)[1])) 
    for(c in 1:dim(clusterCenters)[1]){ 
    center <- clusterCenters[c,] 
    for(v in 1:(dim(clusterMembers)[1])){ 
     vector <- clusterMembers[v,] 
     features[v,c] <- sqrt(sum((center - vector)^2)) 
    } 
    } 
    features 
} 
# my fancy function 
josh <- function() { 
    tcm <- t(clusterMembers) 
    Features <- matrix(0,ncol(tcm),nrow(clusterCenters)) 
    for(i in 1:nrow(clusterCenters)) { 
    # clusterCenters[i,] returns a vector because drop=TRUE by default 
    Features[,i] <- colSums((clusterCenters[i,]-tcm)^2) 
    } 
    Features <- sqrt(Features) # outside the loop to avoid function calls 
} 
system.time(seven()) 
# user system elapsed 
#  2.7  0.0  2.7 
system.time(josh()) 
# user system elapsed 
# 0.28 0.11 0.39 
identical(seven(),josh()) 
# [1] TRUE