Skip to content

How to get all possible combinations?

12 messages · Somnath Dhar, Jorge I Velez, Berend Hasselman +5 more

#
Dear all, suppose I have a vector with elements as:

Vec <- c(2,3,4,5,6)

Now I want to have all possible combination of length 3 using those
elements and without any repetition. Like, I want to have 1
possibility like 2-3-4 but not 3-2-4.

Can somebody guide me how to achieve that in R?

Thanks for your help.
#
On 28-03-2012, at 21:17, Somnath Dhar wrote:

            
?combn

Berend
#
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.

I could do that with loop. Can you suggest something that is more 
elegant and faster?

Thank you
Daniel
#
On Mar 28, 2012, at 4:46 PM, Kehl D?niel wrote:

            
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"
David Winsemius, MD
West Hartford, CT
#
On 28-Mar-2012 Kehl D?niel wrote:
It looks as though you want to do this for each of the 3x3 matrices.
A possible solution could be on the following lines. For compactness
I have reduced your problem to a 4x4 matrix A divided into 4 2x2 blocks.

A:
  A11 A12 A13 A14
  A21 A22 A23 A24
  A31 A32 A33 A34
  A41 A42 A43 A44

If you post-multiply the matrix A by the 4x2 matrix S:

S:
  1  0
  1  0
  0  1
  0  1

then A%*%S gives you

  R11  R12
  R21  R22

where Rij is the 2x1 matrix of row-sums of block (i,j) of A, e.g.

R12:
  A13+A14
  A23+A24

Similarly, if you have a vector B of length 2:

B:
  b1
  b2

and you set up the 4x2 matrix BB:

BB:
  b1  0
  b2  0
  0   b1
  0   b2

then A%*%BB is a 2x2 matrix

  BB11 BB12
  BB21 BB22

where BBij is the result of {Block[i,j] of A}%*%B:

A%*%BB:
  A11 A12 A13 A14 %*%  b1 0
  A21 A22 A23 A24      b2 0
  A31 A32 A33 A34      0  b1
  A41 A42 A43 A44      0  b2

E.g.
BB12:
  A13*b1 + A14*b2
  A23*b1 + A24*b2

This generalises immediately to your 9x9 and a 3-vector.
Setting up the matrices S and BB should be straightforward
(and once done can be applied to any matrix A).

Does this help?

-------------------------------------------------
E-Mail: (Ted Harding) <Ted.Harding at wlandres.net>
Date: 28-Mar-2012  Time: 22:30:45
This message was sent by XFMail
#
see inline.
On Wed, Mar 28, 2012 at 2:46 PM, Kehl D?niel <kehld at ktk.pte.hu> wrote:
A %*% C, where C is a 9x3 matrix
 A <- matrix(1:81, 9, 9)
ones zeros zeros
 [1,]    1     0     0
 [2,]    1     0     0
 [3,]    1     0     0
 [4,]    0     1     0
 [5,]    0     1     0
 [6,]    0     1     0
 [7,]    0     0     1
 [8,]    0     0     1
 [9,]    0     0     1
ones zeros zeros
 [1,]   30   111   192
 [2,]   33   114   195
 [3,]   36   117   198
 [4,]   39   120   201
 [5,]   42   123   204
 [6,]   45   126   207
 [7,]   48   129   210
 [8,]   51   132   213
 [9,]   54   135   216
But from your description I get the new matrix will be 9x3, as above?
[,1]
 [1,]  828
 [2,]  846
 [3,]  864
 [4,]  882
 [5,]  900
 [6,]  918
 [7,]  936
 [8,]  954
 [9,]  972
[1] 828

Kjetil
#
On Wed, Mar 28, 2012 at 10:46:11PM +0200, Kehl D?niel wrote:
Hi.

Try the following, which is based on the solution by Ted Harding.

  # some input
  A <- matrix(1:81, nrow=9, ncol=9)
  B <- 7:5

  # compute the 3 x 3 matrix
  C <- diag(3)[rep(1:3, each=3), ]
  D <- cbind(rbind(B, 0, 0), rbind(0, B, 0), rbind(0, 0, B))
  R1 <- D %*% A %*% C

  # compare with another approach
  E <- A * matrix(B, nrow=9, ncol=9) # component wise product
  C <- diag(3)[rep(1:3, each=3), ]
  R2 <- t(C) %*% E %*% C

  max(abs(R1 - R2)) # [1] 0

Hope this helps.

Petr Savicky.
#
Dear David, Ted, Kjetil, Petr,

thank you, you guys did a great job, I'll use your ideas in the future 
for sure.
After I sent the question I figured a way, see below.

x <- 1:81
b <- 1:3
Q <- matrix(x,9,9)
result <- matrix(matrix(colSums(matrix(t(Q),3)),,3,TRUE) %*% b,3,3)

I hope there is no error in this solution and you can use this idea 
sometime!

Thank you again, have a great day
Daniel

2012.03.29. 8:48 keltez?ssel, Petr Savicky ?rta:
#
On 29-03-2012, at 13:16, Kehl D?niel wrote:

            
Have you compared result with R1 and R2, provided by Petr's solution?

Berend
#
On Thu, Mar 29, 2012 at 01:16:49PM +0200, Kehl D?niel wrote:
Hi.

I am not sure, what was the exact definition of the required
result matrix. The previous solutions yield a different result.
Were they correct?

A solution equivalent to the previous ones, but formatted similarly
to the above is

  b <- 1:3
  Q <- matrix(1:81,9,9)

  tmp <- matrix(colSums(matrix(t(Q),3)),,3,TRUE)
  R3 <- matrix(c(b %*% matrix(tmp, nrow=3)), nrow=3)

  # compare with a previous solution
  E <- Q * matrix(b, nrow=9, ncol=9) # component wise product
  C <- diag(3)[rep(1:3, each=3), ]
  R2 <- t(C) %*% E %*% C

  max(abs(R2 - R3)) # [1] 0

I believe that using dim(Q) <- c(3,3,3,3) and function
aperm() as suggested by David can simplify this approach.

Petr Savicky.
#
On Thu, Mar 29, 2012 at 03:13:25PM +0200, Petr Savicky wrote:
One more approach using aperm().

  b <- 1:3
  Q <- matrix(1:81,9,9)

  A <- Q
  dim(A) <- c(9,3,3)
  A <- aperm(A, perm=c(1, 3, 2))
  dim(A) <- c(27, 3)
  R4 <- matrix(c(b %*% matrix(rowSums(A), nrow=3)), nrow=3)

Petr Savicky.