2012-02-28 2 views
4

속도 최대 매트릭스 rowMeans 동작

nc <- 5000 
nr <- 1024 
m <- matrix(rnorm(nc*nr), ncol=nc) 

가 I이 매트릭스 랜덤 찍은 동일한 크기의 rowMeans 두 그룹 간의 차이를 취할 목적으로, 다음의 행렬을 고려한다.

n <- 1000 # group size 

system.time(replicate(100, { 
    ind1 <- sample(seq.int(nc), n) 
    ind2 <- sample(seq.int(nc), n) 
    rowMeans(m[, ind1]) - rowMeans(m[, ind2]) 
})) 

그것은 아주 천천히, 더 효율적으로 뭔가를

제안 (대부분의 시간 is.data.frame ??에 보냈다는 듯) 불행하게도 나는 Rprof의 출력을 이해하지 못합니까? 내 온라인 독서에서 나는 R의 rowMeans 매우 효율적이라고 생각, 그래서이 단계에서 도움이 될 것이다 분명하지 않다 :

  • Rcpp :

    나는 다음과 같은 고려했다. 병목이 실제로 처음 어디에 있는지 확신하고 싶습니다. 아마도 전체 설계가 차선책 일 수 있습니다. 대부분의 시간이 각각의 더 작은 행렬에 대해 복사하는 데 소비된다면 Rcpp는 더 잘 수행 할 수 있습니까?

  • R-devel로 업데이트하면 더 효율적으로 새로운 .rowMeans 기능이있는 것 같습니다. 아무도 그것을 시도 했습니까?

감사합니다.

+0

, 난 당신이 조금 얻을 의심 것 . RcppArmadillo를 통해 시도 할만큼 빠르지 않아야합니까? –

+0

상당히 쉽습니다. 그렇지만 잘하면 순수 R로 빠져 나갈 수 있습니다. 본질적으로 모든 R 접근이 실패 할 때 시도해 보겠습니다. 또한 Rcpp에서 난수 관리에 대한 경험이 없습니다. – baptiste

+0

Rcpp 설탕은 R이 사용하는 동일한 스트림을 제공합니다 :-) –

답변

7

m에서 컬럼의 서브 세트에 대한 각 호출은 rowSums()m의 행렬 곱셈 및 상기 선택된 항목을 나타내는 0 또는 1의 벡터로 간주 될 수있다. 당신이 모든 벡터를 나란히하는 경우 (훨씬 더 효율적이다) 두 행렬 사이의 곱셈으로 끝낼 : 모든 아르마에서 샘플링, 부분 집합과 차이점을 할 경우

ind1 <- replicate(100, seq.int(nc) %in% sample(seq.int(nc), n)) 
ind2 <- replicate(100, seq.int(nc) %in% sample(seq.int(nc), n)) 
output <- m %*% (ind1 - ind2) 
+0

, 감사합니다! 나는 그것이 옳은 일을한다고 스스로에게 확신시켜야 할 것이다. 그러나 그것은 분명 빠르고 빠르다. – baptiste

4

rowMeans을 2 번 호출 할 필요가 없습니다. 먼저 빼기를 수행하고 결과에 rowMeans을 호출 할 수 있습니다.

x1 <- rowMeans(m[,ind1])-rowMeans(m[,ind2]) 
x2 <- rowMeans(m[,ind1]-m[,ind2]) 
all.equal(x1,x2) 
# [1] TRUE 

is.data.framerowMeans 이루어 검사의 일부이다.

업데이트 : R-devel에 관한 .rowMeans에 대해서는 내부 코드에 대한 바로 호출과 같습니다 (do_colsum은 변경되지 않았다고 가정).

.rowMeans <- function(X, m, n, na.rm = FALSE) 
    .Internal(rowMeans(X, m, n, na.rm)) 
귀하의 경우에는

, m=1024n=1000 : 그것은 다음과 같이 정의합니다.

+0

실제로 OP는 1로 줄일 수있는'rowMeans'에 200 번의 호출 (2 * 100 복제)을하기 때문에 말하기보다 훨씬 낫습니다. .. rm <- rowMeans (m); (초, (nc), (nc), n)])') 0.1 경과 된 초 걸립니다 ... (replicate (100, {rm [sample (seq.int (nc), n)] - –

+0

@ Joshua 두 행렬의 diff를 취하는 것이 그 중 하나의 rowMeans를 계산하는 것만 큼 비싸지 않을 것이라고 확신합니까? 그것은 결국 같은 수의 작업입니다. – flodel

+0

@BenBolker. 또한'rowMeans (m)'이'replicate' 호출의 외부에 저장 될 수 있다고 생각 했었지만 같은 문제를 해결하지는 못했습니다. OP의 출력은 1024 x 10입니다. 당신과 내가 둘 다 생각한 것은 1000x10이 될 것입니다. – flodel