[R] A question to get all possible combinations

Daniel Nordlund djnordlund at frontier.com
Wed Dec 22 23:51:42 CET 2010


> -----Original Message-----
> From: r-help-bounces at r-project.org [mailto:r-help-bounces at r-project.org]
> On Behalf Of Ted Harding
> Sent: Wednesday, December 22, 2010 2:39 PM
> To: r-help at r-project.org
> Subject: Re: [R] A question to get all possible combinations
> 
> On 22-Dec-10 18:19:38, Ron Michael wrote:
> > Let say, I have a matrix with 8 rows and 6 columns:_
> > df1 <- matrix(NA, 8, 4)
> > df1
> >      [,1] [,2] [,3] [,4]
> > [1,]   NA   NA   NA   NA
> > [2,]   NA   NA   NA   NA
> > [3,]   NA   NA   NA   NA
> > [4,]   NA   NA   NA   NA
> > [5,]   NA   NA   NA   NA
> > [6,]   NA   NA   NA   NA
> > [7,]   NA   NA   NA   NA
> > [8,]   NA   NA   NA   NA
> >
> > Now I want to get **all possible** ways to fetch 6 cells at
> > a time. Is there any function to do that?
> > Thanks,
> 
> If you just want all possible sets of 6 values (i.e. the values
> at 6 different cells, for all possible choices of 6 out of 8*4 = 32)
> then it is straightforward enough using the combn() function.
> I give a smaller example to show the principle. You get the 20 ways
> of choosing the values in 3 different cells of a 6-cell (3*2) matrix:
> 
>   df1 <- matrix((1:6),ncol=2)
>   df1
>   #      [,1] [,2]
>   # [1,]    1    4
>   # [2,]    2    5
>   # [3,]    3    6
> 
>   combn(df1,3)
>       [,1]  [,2]  [,3]  [,4]  [,5]  [,6]  [,7]  [,8]  [,9] [,10]
> [1,]     1     1     1     1     1     1     1     1     1     1
> [2,]     2     2     2     2     3     3     3     4     4     5
> [3,]     3     4     5     6     4     5     6     5     6     6
>      [,11] [,12] [,13] [,14] [,15] [,16] [,17] [,18] [,19] [,20]
> [1,]     2     2     2     2     2     2     3     3     3     4
> [2,]     3     3     3     4     4     5     4     4     5     5
> [3,]     4     5     6     5     6     6     5     6     6     6
> 
> This basically works because the elements of a matrix are stored
> linearly (1->2->3->4->5->6) down the columns, with a "dim" attribute
> to sort out the indexing by rows and columns. combn(df1,3) then
> picks out all sets of 3 from these 6 and returns the results in
> "natural" order.
> 
> However, this result loses all information about the row-column
> indexing of the values which are returned.
> 
> Getting at this is a little trickier. There may be some function
> which can do it directly, though I don't know of one. An alternative
> (the least subtle I can think of ... ) could be to do the same combn()
> operation on vectors which gives the rows and columns of the elements
> in the matrix df1:
> 
> The result of combn() is a list, as above, and you can make it a
> linear vector with:
> 
>   as.vector(combn(df1,3))
>   #  [1] 1 2 3 1 2 4 1 2 5 1 2 6 1 3 4 1 3 5 1 3 6 1 4 5 1 4 6 1 5 6
>     [16] 2 3 4 2 3 5 2 3 6 2 4 5 2 4 6 2 5 6 3 4 5 3 4 6 3 5 6 4 5 6
> 
> Now you can do the same with the columns of a matrix which carries
> the row indices and the column indices:
> 
>   RC <- cbind(Row=rep(c(1,2,3),2),Col=rep(c(1,2),each=3))
>   RC
>   #      Row Col
>   # [1,]   1   1
>   # [2,]   2   1
>   # [3,]   3   1
>   # [4,]   1   2
>   # [5,]   2   2
>   # [6,]   3   2
> 
> Now:
>   df1.3 <- as.vector(combn(df1,3))
>   ix.RC <- combn((1:nrow(RC)),3)
>   All   <- cbind(RC[ix.RC,],df1.3)
>   colnames(All) <- c("Row","Col","Val")
>   All
>   #       Row Col   Val
>   #  [1,]   1   1     1
>   #  [2,]   2   1     2
>   #  [3,]   3   1     3
>   #  [4,]   1   1     1
>   #  [5,]   2   1     2
>   #  [6,]   1   2     4
>   #  [7,]   1   1     1
>   #  [8,]   2   1     2
>   #  [9,]   2   2     5
>   # [10,]   1   1     1
>   # [11,]   2   1     2
>   # [12,]   3   2     6
>   # .................
>   # [49,]   3   1     3
>   # [50,]   1   2     4
>   # [51,]   2   2     5
>   # [52,]   3   1     3
>   # [53,]   1   2     4
>   # [54,]   3   2     6
>   # [55,]   3   1     3
>   # [56,]   2   2     5
>   # [57,]   3   2     6
>   # [58,]   1   2     4
>   # [59,]   2   2     5
>   # [60,]   3   2     6
> 
> in which each block of 3 successive rows gives you the 3 Rows,
> the 3 Columns, and the 3 Values for one of the 20 possible
> choices of 3 cells out of the 6 in the matrix. You could
> subsequently rearrange this to suit your purposes.
> 
> Ted.
> 

I see lots of good ideas and sample code, but what I haven't seen is the OP clarifying what is REALLY wanted.  The original statement specified 8 rows and 6 columns, but the example was 8 rows by 4 columns.  It is also not clear if what is wanted is ANY 6 cells out of  all 48 (or 32) cells or, one from each column, or ....  It would be unfortunate if all this good work is solving the wrong problem.

Dan

Daniel Nordlund
Bothell, WA USA



More information about the R-help mailing list