2012-02-25 3 views
15

각 열에 최대 하나가되도록 행렬의 값을 조정하려고합니다. 나는 시도했다 :열을 colSum 단위로 나누기 R

m = matrix(c(1:9),nrow=3, ncol=3, byrow=T) 
    [,1] [,2] [,3] 
[1,] 1 2 3 
[2,] 4 5 6 
[3,] 7 8 9 

colSums(m) 
12 15 18 

m = m/colSums(m) 
      [,1]  [,2] [,3] 
[1,] 0.08333333 0.1666667 0.25 
[2,] 0.26666667 0.3333333 0.40 
[3,] 0.38888889 0.4444444 0.50 

colSums(m) 
[1] 0.7388889 0.9444444 1.1500000 

명백하게 이것은 작동하지 않는다. 나는 다음이 시도 :

m = m/matrix(rep(colSums(m),3), nrow=3, ncol=3, byrow=T) 
      [,1]  [,2]  [,3] 
[1,] 0.08333333 0.1333333 0.1666667 
[2,] 0.33333333 0.3333333 0.3333333 
[3,] 0.58333333 0.5333333 0.5000000 

m = colSums(m) 
[1] 1 1 1 

그래서이 작품을,하지만 난 여기에 뭔가 빠진 것 같은이 느낌. 이것은 일상적으로 수행되는 방법이 될 수 없습니다. 나는 여기서 바보가된다고 확신한다. 당신이 줄 수 어떤 도움 건배,

답변

38

?sweep를 참조 데비, 예를 감상 할 수있다 :

> sweep(m,2,colSums(m),`/`) 
      [,1]  [,2]  [,3] 
[1,] 0.08333333 0.1333333 0.1666667 
[2,] 0.33333333 0.3333333 0.3333333 
[3,] 0.58333333 0.5333333 0.5000000 

또는 행렬을 전치 할 수 다음 colSums(m)가 제대로 재생됩니다. 이런 식으로, 이후 다시 전치하는 것을 잊지 마세요 :

> t(t(m)/colSums(m)) 
      [,1]  [,2]  [,3] 
[1,] 0.08333333 0.1333333 0.1666667 
[2,] 0.33333333 0.3333333 0.3333333 
[3,] 0.58333333 0.5333333 0.5000000 

또는 당신은 기본적으로 동일 할 기능 prop.table()를 사용

> prop.table(m,2) 
      [,1]  [,2]  [,3] 
[1,] 0.08333333 0.1333333 0.1666667 
[2,] 0.33333333 0.3333333 0.3333333 
[3,] 0.58333333 0.5333333 0.5000000 

시간 차이가 다소 작다. sweep() 기능과 t() 트릭이 가장 유연한 솔루션입니다. prop.table()은이 특별한 경우에만 해당합니다.

+0

브릴리언트. 고맙습니다! 부끄러워 내가 prop.table()에 대해 완전히 잊었다. –

5

평소와 달리 Joris는 훌륭한 답변을 제공합니다. 마음에 온 두 사람 :

#Essentially your answer 
f1 <- function() m/rep(colSums(m), each = nrow(m)) 
#Two calls to transpose 
f2 <- function() t(t(m)/colSums(m)) 
#Joris 
f3 <- function() sweep(m,2,colSums(m),`/`) 

요리스 '대답은 내 컴퓨터에서 가장 빠른 것입니다 :

> m <- matrix(rnorm(1e7), ncol = 10000) 
> library(rbenchmark) 
> benchmark(f1,f2,f3, replications=1e5, order = "relative") 
    test replications elapsed relative user.self sys.self user.child sys.child 
3 f3  100000 0.386 1.0000  0.385 0.001   0   0 
1 f1  100000 0.421 1.0907  0.382 0.002   0   0 
2 f2  100000 0.465 1.2047  0.386 0.003   0   0 
+1

내 게시물이 좋아 보이고 편집 내용이 서로 전달되었습니다. 칭찬을위한 Thx. –

+0

당신이 거대한 데이터 세트를 다루지 않는다면, 나는 표현력 때문에 '스윕 (swep)'을 좋아한다. 귀여움을 위해서, exp (scale (log (m), center = TRUE, scale = FALSE)' 많은 이유 때문에 좋은 생각이 아닙니다!) –

+3

또는'scale (m, center = FALSE, scale = colSums (m))'. – flodel

관련 문제