[R] simple matrix calculation

David Winsemius dwinsemius at comcast.net
Thu Mar 29 00:01:46 CEST 2012


On Mar 28, 2012, at 4:46 PM, Kehl Dániel wrote:

> Dear list-members,
>
> I have a 9-by-9 matrix lets call it A with first row a11, a12,  
> a13,..., a19 etc.
> I also have a vector of length 3 (B).
> I want to construct a matrix of size 3x3 in the following way:
> - divide matrix A to 9 3x3 blocks
> - first is
>        a11, a12, a13
>        a21, a22, a23
>        a31, a32, a33
> - I want to get rowSums of this A1 matrix
> - Multiply A1*B and get a scalar, the first element of my new 3x3  
> matrix.
>

You're going to need some sort of loop,  but maybe you can make it  
more elegant my noticing that you can access the 3x3 elements more  
elegantly using single subscript values rather than ranges:

  amat <- matrix(paste("a", rep(1:9, time=9), rep(1:9, each=9),  
sep=""), 9,9)
amat
       [,1]  [,2]  [,3]  [,4]  [,5]  [,6]  [,7]  [,8]  [,9]
  [1,] "a11" "a12" "a13" "a14" "a15" "a16" "a17" "a18" "a19"
  [2,] "a21" "a22" "a23" "a24" "a25" "a26" "a27" "a28" "a29"
  [3,] "a31" "a32" "a33" "a34" "a35" "a36" "a37" "a38" "a39"
  [4,] "a41" "a42" "a43" "a44" "a45" "a46" "a47" "a48" "a49"
  [5,] "a51" "a52" "a53" "a54" "a55" "a56" "a57" "a58" "a59"
  [6,] "a61" "a62" "a63" "a64" "a65" "a66" "a67" "a68" "a69"
  [7,] "a71" "a72" "a73" "a74" "a75" "a76" "a77" "a78" "a79"
  [8,] "a81" "a82" "a83" "a84" "a85" "a86" "a87" "a88" "a89"
  [9,] "a91" "a92" "a93" "a94" "a95" "a96" "a97" "a98" "a99"

  > dim(amat) <- c(3,3,3,3)
  > amat[,1,,1]  # upper/left 3x3
      [,1]  [,2]  [,3]
[1,] "a11" "a12" "a13"
[2,] "a21" "a22" "a23"
[3,] "a31" "a32" "a33"

 > amat[,2,,2]  # middle/middle 3x3
      [,1]  [,2]  [,3]
[1,] "a44" "a45" "a46"
[2,] "a54" "a55" "a56"
[3,] "a64" "a65" "a66"

If speed is an issue than perhaps you could use `aperm` to rearrange  
this 3x3x3x3 array so that the proposed rowSums operation would be  
correct (within three row segments.)

 > newmat <- aperm(amat, c(2,4,3,1))
 > dim(newmat) <- c( 3*9,3)
 > newmat[1:6,1:3]
      [,1]  [,2]  [,3]
[1,] "a11" "a21" "a31"
[2,] "a41" "a51" "a61"
[3,] "a71" "a81" "a91"
[4,] "a14" "a24" "a34"
[5,] "a44" "a54" "a64"
[6,] "a74" "a84" "a94"


> I could do that with loop. Can you suggest something that is more  
> elegant and faster?
>
> Thank you
> Daniel
>
> ______________________________________________
> R-help at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
> and provide commented, minimal, self-contained, reproducible code.

David Winsemius, MD
West Hartford, CT



More information about the R-help mailing list