Combinations


Return to Topics page

Combinations are different ways of selecting items from a group. The key concept is that the order of the chosen items is not important. If we have four things, A, B, C, and D, then we can select two items in any one of six ways, AB, AC, AD, BC, BD, and CD. Because order is not important, the choice DA is already in our list of six in the form AD.

Another example would be to start with five things, say cat, dog, eel, fox, and goat. Then we could ask for the combinations of those five things taken three at a time. That is, find the different groups of three things that we can make using just the five things cat, dog, eel, fox, and goat. That will be the 10 groups 1:cat dog eel, 2: cat dog fox, 3:cat dog goat , 4:cat eel fox, 5:cat eel goat, 6:cat fox goat, 7:dog eel fox, 8:dog eel goat , 9:dog fox goat, and 10:eel fox goat. Thus, there are 10 combinations of 5 things taken 3 at a time. We note that the group fox cat eel is already in the answer as cat eel fox because the order of items in the group is not important.

Clearly there are two related but different tasks here. One is to be able to construct the different combinations and the other is to predict the number of combinations that we will find. R can help us with both of these. Unfortunately, that help will take a little bit of extra effort (this effort is the same as that done for permutations and it need not be repeated if it was already done in our RStudio or R session).

This next section presents the "combinations" function. Although it is nice to see it, this class does not require you to use it. For this class we will get a smaller, easier to use function, in fact we will get two of them, to mimic the function available on the TI-83/84 calculators. Those functions are presented later on this page.
Bill Venables, and later Gregory R. Warnes, developed and refined a special function that constructs combinations. That function is not part of the base R installation. Instead, that function is provided in a package that is called "gtools". In order for us to use that function we must do two things. First we need to actually get the package and second we need to load it into our R session. Fortunately the commands to do both of these are quite short. They are
install.packages("gtools")
library(gtools)
Once we have performed those two statements within our session we will be able to use the combinations() function. Figure 1 shows the console screen that reflects doing those two commands.

Figure 1

Following the installation shown in Figure 1 we can give the command combinations(4, 2, letters[1:4]) which is a call to the combinations() function, telling it that it should use the 4 values in the third argument and to use them 2 at a time to form all of the possible combinations that it can. The third argument, letters[1:4] provides the letters "a", "b", "c" and "d" for combinations() to use as the values. Figure 2 shows the result of that command.

Figure 2

That is the same result, but with lower case letters, that we saw in the example used at the top of the page. We can do the second example, the one looking at the combinations of cat, dog, eel, fox, and goat taken 3 at a time via the command combinations(5,3,c("cat","dog","eel","fox","goat")). This is shown in Figure 3.

Figure 3

It should be clear from Figure 2 and Figure 3 that we could use the R function combinations() to not only produce the possible combinations but also to find the number of such combinations.

Before we go any further, we should pause for a moment and find some way to symbolize "the number of of combinations of n things take r at a time." As was the case with permutations there are many such symbols. Unfortunately, there has not been any agreement on the most acceptable form for such symbolism. One form nCr has a small advantage in that it is the form used by the TI-83/84 calculators. On such a calculator one would enter 12nCr7 to find the number of combinations of 12 things taken 7 at a time. However, in a textbook or paper, the symbol for that specific computation would be 12C7. Table 1 gives some the general and specific forms of the ways we put "the number of of combinations of n things take r at a time" into symbols.


The final form in Table 1, , is often seen in math classes, but here we will try to consistently use the general form nCr, or in specific problems the 12C7 form.

The combinations of taking 5 things, 3 at a time were illustrated above in Figure 3. There we found that there were 10 such combinations. Each of those combinations has 3 things in it. We recall that the number of permutations of 3 things taken 3 at a time is 3! = 3*2*1 = 6. In our earlier example, one of the combinations was cat eel goat. But this could be arranged as 1:cat eel goat, 2:cat goat eel, 3:eel cat goat, 4:eel goat cat, 5:goat cat eel, or 6:goat eel cat. Therefore, each of the 10 groups representing a different combination of 3 things taken from the original 5 things could be arranged in 6 ways. If we did that then we would have the 60 permutations of 5 things taken 3 at a time, 5P3 = 5! / (5-3)! = 5! / 2! = 5*4*3 = 60 =10*6 = 5C3*3P3. That is, 5P3 is equal to 5C3 times 3P3.

There is no trick here as concerns the numbers we are using. It is always the case that
nPr = nCr * rPr
Of course we can solve that equation for nCr to get
nCr = nPr / rPr
This formula is all we need to construct a function in R to compute the number of combinations of n things taken r at a time.
Here is where we develop our own functions for finding the number of combinations of n things taken r at a time.
The code for such a function is
num_comb <- function( n, r )
{ if( r == 0 ) {return(1)}
  if( r > n/2 ) { r <- n-r}
  return( num_perm(n,r)/num_perm(r,r))
}
and Figure 4 shows that function entered into an R session.

Figure 4

We note that R accepted the form of the function in that Rgave no error message at this point. A second confirmation of this is that the function is now defined in the environment pane of our RStudio session.

Figure 5

Even though there was no error in the way we wrote num_comb(), examining the Environment pane in Figure 5 reveals that the function num_comb() will not work in this R session. It will not work because we wrote the function to use another funcion, namely, num_perm(), and that function has not been defined in this session.

To fix this problem we will have to define num_perm(). This is shown in Figure 6.

Figure 6

We revisit the Environment pane and now both functions are defined.

Figure 7

Figure 7 shows two example calls to the num_comb() function. The first asks for the number of combinations of 4 things taken 2 at a time. The second asks for the number of combinations of 5 things taken 3 at a time. We already knew these answers from Figure 2 and Figure 3, respectively.

Figure 8

In Figure 9 we look at all the other possible requests for combinations involving 5 things.

Figure 9

The results shown in Figure 9 are worth some examination and consideration. In the first place, 5C2 is 10, exactly the same value that we had for 5C3. This is not a coincidence! If we have 5 items, say A, B, C, D, and E, and we select 3 of them, perhaps A C D, then there are exactly 2 that we did not select; in our example that would be B E. In fact, each time we select 3 items for 5C3 the 2 items not selected will be one of the combinations that make up 5C2.

This same pattern is shown in comparing 5C1 and 5C4. Each time we select 1 item for 5C1 the 4 items not selected will be one of the combinations that make up 5C4. In general, it is always true that nCr = nC(n-r). We actually used that fact in the definition of num_comb() when we included
if( r > n/2 ) { r <- n-r}
That line means that if we ask for num_comb(12,9) then the function really computes num_comb(12,3). We did this because it makes the computation shorter. Both num_perm(12,9) and num_perm(9,9) have 9 factors. However, each of num_perm(12,3) and num_perm(3,3) have only 3 factors.

The second thing to note from Figure 9 is that 5C0 is 1. This does raise the question of what it means to have 5 things and take them 0 at a time? We can answer that by following the same pattern that we just saw in understanding why 5C3 = 5C2. Our understanding of that is that each combination of 3 things taken fom our 5 things leaves a combination of 2 things. Using that pattern we know that 5C5 = 5C0. Our understanding is that each combination of 5 things taken fom our 5 things leaves a combination of 0 things. But our combination of 5 things is all of them and that leaves the empty set as as the one and only combination of 0 of the original 5. Therefore, 5C0 is 1.

A third thing to note from Figure 9 (and Figure 8) is that if we look at the values in the following order 5C0, 5C1, 5C2, 5C3, 5C4, and 5C5, then we get 1 5 10 10 5 1. That is exactly row 5 of Pascal's Triangle, the top of which is shown in Figure 10.
Figure 10

Each row of the triangle starts with and ends with a 1. Internal values in a row are just the sum of the two values in the previous row that are above and to the left and right of the position of that internal number. Thus, in row 6 (the top row is row 0), the value 15 is just the sum of the 5 and 10 in row 5.

Pascal's Triangle gives us the "binomial coefficients" for the expansion of an expression such as (x+y)5. Thus,
(x+y)5 = 1x5y0 + 5x4y1 + 10x3y2 + 10x2y3 + 5x1y4 + 1x0y5


Leading up to the development of the num_comb() function above, we had
nCr = nPr / rPr
But we already have a formula for permutations so we know that
nPr = n! / (n-r)!     and     rPr = r! / (r-r)! = r! / 0! = r! =r!
Therefore, we could rewrite our equation for combinations as
nCr = ( n! / (n-r)! ) / (r!)
This is mathematically equivalent to
nCr = n! / ( (n-r)! * r! )
This is the usual statement of the formula for the number of combinations of n things taken r at a time, although it is most often written in a more conventional fraction form as

This allows us to construct a new function to compute nCr, but this time without having to make reference to the num_perm() function. The code for the new function is
nCr <- function(n,r )
{ return ( factorial(n)/factorial(n-r)/factorial(r))}
and Figure 11 shows the function as entered into an RStudio session.

Figure 11

Checking the Environment pane shows the new function.

Figure 12

And, finally, we can use the statements nCr(4,2), nCr(5,3), and nCr(12,7) to test out the new function, as shown in Figure 13.

Figure 13

Return to Topics page
©Roger M. Palay     Saline, MI 48176     December, 2015