[R] run function on subsets of matrix
peter dalgaard
pdalgd at gmail.com
Sun Mar 27 09:22:00 CEST 2011
On Mar 27, 2011, at 08:25 , David Winsemius wrote:
>
> On Mar 26, 2011, at 10:26 PM, fisken wrote:
>
>> I was wondering if it is possible to do the following in a smarter way.
>>
>> I want get the mean value across the columns of a matrix, but I want
_along_ the columns, I assume.
>> to do this on subrows of the matrix, given by some vector(same length
>> as the the number of rows). Something like
>>
>> nObs<- 6
>> nDim <- 4
>> m <- matrix(rnorm(nObs*nDim),ncol=nDim)
>> fac<-sample(1:(nObs/2),nObs,rep=T)
>>
>> ##loop trough different 'factor' levels
>> for (i in unique(fac))
>> print(apply(m[fac==i,],2,mean))
>
> This would be a lot simpler and faster:
>
> colMeans(m[unique(fac),])
>
> #[1] 1.3595197 -0.1374411 0.1062527 -0.3897732
>
Say what??? (I suspect David needs to get his sleep - or coffee, if he is in Europe.)
How about:
> aggregate(m,list(fac),mean)
Group.1 V1 V2 V3 V4
1 1 -0.03785420 -0.2573805 -0.3025759 0.006999996
2 2 -1.39961300 0.2296900 -0.1122359 -0.302734531
3 3 0.50886649 0.6546153 -0.4270368 -0.411807709
> by(m,list(fac),colMeans)
: 1
V1 V2 V3 V4
-0.037854195 -0.257380542 -0.302575901 0.006999996
-------------------------------------------------------------
: 2
V1 V2 V3 V4
-1.3996130 0.2296900 -0.1122359 -0.3027345
-------------------------------------------------------------
: 3
V1 V2 V3 V4
0.5088665 0.6546153 -0.4270368 -0.4118077
>
(whereas
> fac
[1] 3 1 1 2 3 1
> colMeans(m[unique(fac),])
[1] 0.39949029 -0.10989080 -0.96655778 0.01262903
> colMeans(m[1:3,])
[1] 0.39949029 -0.10989080 -0.96655778 0.01262903
)
>>
>> Now, the problem is that if a value in 'fac' only occurs once, the
>> 'apply' function will complain.
>
> Because "[" will drop single dimensions and so the matrix becomes a vector and looses the number-2 margin. Use drop=FALSE to prevent this, and note the extra comma:
>
> print(apply(m[1, , drop=FALSE],2,mean))
Yep.
--
Peter Dalgaard
Center for Statistics, Copenhagen Business School
Solbjerg Plads 3, 2000 Frederiksberg, Denmark
Phone: (+45)38153501
Email: pd.mes at cbs.dk Priv: PDalgd at gmail.com
More information about the R-help
mailing list