2014-10-14 2 views
2

죄송합니다. 이것은 사소한 것처럼 보이지만 잠시 인터넷을 검색 한 후에 해결할 수 없습니다.R : 행렬에 ave()를 적용하는 간단한 방법이 있습니까?

필자는 행렬과 관련된 요소 벡터를 가지고 있습니다. 목표는 모든 요소에 대해 개별적으로 rowMeans를 가져 와서 원래의 행렬 구조를 유지하는 것입니다. 그래서 아마 ave()와 같은 것이지만 2 차원 배열에서 작업 할 것입니다.

(mat <- rbind(1:5,6:10,11:15)) 
    [,1] [,2] [,3] [,4] [,5] 
[1,] 1 2 3 4 5 
[2,] 6 7 8 9 10 
[3,] 11 12 13 14 15 

groups <- c(1,1,1,2,2) 

mat[,groups==1] <- rowMeans(mat[,groups==1]) # I am asking about this part 
mat[,groups==2] <- rowMeans(mat[,groups==2]) # ... 

mat 
    [,1] [,2] [,3] [,4] [,5] 
[1,] 2 2 2 4.5 4.5 
[2,] 7 7 7 9.5 9.5 
[3,] 12 12 12 14.5 14.5 

실제로이 행렬 행 (적은 열)의 수백만 것 :

는 여기에 원유 데모입니다. 행 단위로 작동하는 솔루션이 너무 느릴 수 있습니다.

내 기능을 작성하는 중입니다. 그러나 이것은 쉬운 한 줄짜리 해결책이있는 것 같습니다.

ave(m, row(m)) 

그게 당신이 제공하시기 바랍니다하지 것입니다 경우 m 당신의 행렬이다

답변

2

:

2) 업데이트 된 질문에 대해이 시도

mat.list <- Map(matrix, split(mat, groups[col(mat)]), nrow = nrow(mat)) 
mean.list <- Map(rowMeans, mat.list) 
do.call(cbind, mean.list[groups]) 

를 이상 속도 :

idx.list <- split(seq_len(ncol(mat)), groups) 
get.cols <- function(mat, idx) mat[, idx, drop = FALSE] 
mat.list <- lapply(idx.list, get.cols, mat = mat) 
mean.list <- lapply(mat.list, rowMeans) 
do.call(cbind, mean.list[groups]) 
+0

기꺼이 답변을 수락합니다. 그것은 정확하고 나에게 새로운 아이디어를주었습니다. 그러나 나는 루프가이 경우 이해하기가 더 쉬울 것 같아서 :) 실제로 몇 가지 기본적인 한 단어 기능이 누락되었다고 생각했습니다. –

3

1) 해당 행의 평균이 각 행의 모든 ​​요소를 ​​대체 할 것으로 가정하면,이 시도 입력과 desried 출력을 포함한 완전한 예제.

t(ave(t(m), group, t(row(m)))) 

하거나 상응하는 변화 :이 같은 어쩌면

ave(m, matrix(group, nrow(m), ncol(m), byrow = TRUE), row(m)) 
+0

두 번째 예제가 가까이에 있다고 생각합니다. 그러나 그것은 내 손에 원하는 결과를 재현하지 않습니다. 즉 나는 매트 [2,] : (6.0 7.5 7.5 9.0 10.0)을 얻는다. (7 7 7 9.5 9.5)이어야합니다. –

+0

좋은 지적입니다. 개정판을 참조하십시오. –

+0

흥미로운 접근 방법. 오늘 너에게서 몇 가지 것을 배웠다. (row() 또는 col()을 인식하지 못했습니다). –

1

rowGroupMeans와 같은 최적화 된 함수가 있으면 좋겠지 만, 그런 것은 알지 못합니다.

means <- rowsum(t(mat), groups)/tabulate(groups) 
t(means)[, groups] 

     1 1 1 2 2 
[1,] 2 2 2 4.5 4.5 
[2,] 7 7 7 9.5 9.5 
[3,] 12 12 12 14.5 14.5 

이 더 큰 문제, 예를 들어,에 아주 잘 확장 다음과 같이

내 솔루션, rowsum를 사용하는 것입니다

mat <- matrix(1:100e6, ncol = 100) 
groups <- rep(1:10, each = 10) 

## Map solution 
for (i in 1:3){ 
    print(system.time({ 
     mat.list <- Map(matrix, split(mat, groups[col(mat)]), nrow = nrow(mat)) 
     mean.list <- Map(rowMeans, mat.list) 
     ans1 <- do.call(cbind, mean.list[groups]) 
    })) 
} 

    user system elapsed 
    8.20 1.26 9.66 
    user system elapsed 
    11.84 1.94 13.90 
    user system elapsed 
    10.70 1.89 12.79 

## rowsum solution 
for (i in 1:3){ 
    print(system.time({ 
     means <- rowsum(t(mat), groups)/tabulate(groups) 
     ans2 <- t(means)[,groups] 
    })) 
} 

    user system elapsed 
    1.56 0.22 1.78 
    user system elapsed 
    1.48 0.27 1.74 
    user system elapsed 
    1.57 0.14 1.72 

은 이미 ave 솔루션은 확장 성이 좋지 않습니다주의 -이에 대한 타이밍을 실행하려고 할 때 내 R 세션이 추락했다.

+0

응답 해 주셔서 감사합니다. 귀하의 솔루션은 rowMeans에 대해 가장 우아하고 정말 빠릅니다. 그러나 나는 "rowMeans"를 예제로 사용했으며 (분명히 명확하지 않았을 수도 있음) 완전한 ave() 유형 접근법을 목표로 삼았습니다. 즉, 다른 유형의 함수 (예 : rowMedians)를 지정할 수 있기를 원합니다. 아마 내가이 포장지를 작성하려고합니다. 모든 대답은 나에게 약간의 아이디어를 주었다. 다시 감사합니다. –

관련 문제