Lab 02

Author

SYDNEY NOELL :)

Published

January 24, 2024

This lab is organized in 2 sections: Tutorial & Tasks

The tutorial section will introduce new R commands, and the Tasks have you practice using those commands to answer questions. You should turn in this lab with all Tasks completed.

Let’s first begin by loading the package we will need in this Lab: gtools. You may need to install the package first by running install.packages("gtools") in your console. You can think of a package like an app on your phone: you only need to install it once, but you must “open” it each time you want to use it. In order to “open” (i.e. “load”) the package, we use the library() command.

library(gtools)

Note that R typically prints out lots of messages when we load packages, but we set message: false when defining the code chunk above to suppress the messages and de-clutter our html document.

Tutorial

Methods of Enumeration (Book Section 1.2) in R

[Note: In order to view the mathematical formulas in this section, it will be easiest to read this section in the rendered .html OR by reading the .qmd in “Visual” mode; you can toggle between “Source” and “Visual” mode using the toolbar in the top left of RStudio . If you’re curious, comparing the syntax inside the dollar signs in the “Source” mode to the formatted formulas in the html document will give you insight into how to type pretty math text using LaTeX!].

Factorials

Recall that \[n! = n \cdot (n-1) \cdot (n-2) \cdots 3 \cdot 2\cdot 1\]

Therefore, if \(n = 7\) then \(n! = 7! = 7 \cdot 6 \cdot 5 \cdot 4 \cdot 3 \cdot 2 \cdot 1 = 5040\). The function factorial() in R computes \(n!\) for any integer input n. The code below computes 7! and returns the value 5040.

factorial(7)
[1] 5040

Combinations

Recall that the number of combinations \(_nC_k\) (read “n choose k”) is defined as \[_nC_k = {n\choose k} = \frac{n!}{k!(n-k)!}\]

The number of possible combinations can be easily computed in R using the function choose(). This function takes in two arguments, named - you guessed it - n and k. The following code computes \[_5C_3 = {5\choose 3} = \frac{5!}{3!(5-3)!}\] and returns the value 10.

choose(n = 5, k = 3)
[1] 10

Note the code choose(5, 3) will return the same result because R automatically assigns the first input to the argument n and the second input to the argument k, without us having to specify the name of the argument.

choose(5, 3)
[1] 10

The function combinations() will actually list all the possible combinations. That is, the code combinations(5,3) will list the 10 different ways it is possible to choose 3 elements from a list of 5 elements.

combinations(5, 3)
      [,1] [,2] [,3]
 [1,]    1    2    3
 [2,]    1    2    4
 [3,]    1    2    5
 [4,]    1    3    4
 [5,]    1    3    5
 [6,]    1    4    5
 [7,]    2    3    4
 [8,]    2    3    5
 [9,]    2    4    5
[10,]    3    4    5

Instead of just generic number orderings, you can also provide the function with a vector of names/labels to choose from. For example, if we create a vector of names (called names) of the five people in Dr. Fitz’s immediate family, combinations(5, 3, names) will return the 10 combinations of 3 people we could choose from her family.

names <- c("Jim", "Liz", "Erin", "Katie", "Anna")
combinations(5, 3, names)
      [,1]   [,2]    [,3]   
 [1,] "Anna" "Erin"  "Jim"  
 [2,] "Anna" "Erin"  "Katie"
 [3,] "Anna" "Erin"  "Liz"  
 [4,] "Anna" "Jim"   "Katie"
 [5,] "Anna" "Jim"   "Liz"  
 [6,] "Anna" "Katie" "Liz"  
 [7,] "Erin" "Jim"   "Katie"
 [8,] "Erin" "Jim"   "Liz"  
 [9,] "Erin" "Katie" "Liz"  
[10,] "Jim"  "Katie" "Liz"  

Permutations

Recall that permutations give the total number of ways to order \(k\) unique subjects, selected from \(n\) subjects. Our mathematical formula is \[_nP_k = \frac{n!}{(n - k)!}\]

In a similar fashion to combinations(), the function permutations() returns a matrix of all the possible permutations.

permutations(5, 3, names)
      [,1]    [,2]    [,3]   
 [1,] "Anna"  "Erin"  "Jim"  
 [2,] "Anna"  "Erin"  "Katie"
 [3,] "Anna"  "Erin"  "Liz"  
 [4,] "Anna"  "Jim"   "Erin" 
 [5,] "Anna"  "Jim"   "Katie"
 [6,] "Anna"  "Jim"   "Liz"  
 [7,] "Anna"  "Katie" "Erin" 
 [8,] "Anna"  "Katie" "Jim"  
 [9,] "Anna"  "Katie" "Liz"  
[10,] "Anna"  "Liz"   "Erin" 
[11,] "Anna"  "Liz"   "Jim"  
[12,] "Anna"  "Liz"   "Katie"
[13,] "Erin"  "Anna"  "Jim"  
[14,] "Erin"  "Anna"  "Katie"
[15,] "Erin"  "Anna"  "Liz"  
[16,] "Erin"  "Jim"   "Anna" 
[17,] "Erin"  "Jim"   "Katie"
[18,] "Erin"  "Jim"   "Liz"  
[19,] "Erin"  "Katie" "Anna" 
[20,] "Erin"  "Katie" "Jim"  
[21,] "Erin"  "Katie" "Liz"  
[22,] "Erin"  "Liz"   "Anna" 
[23,] "Erin"  "Liz"   "Jim"  
[24,] "Erin"  "Liz"   "Katie"
[25,] "Jim"   "Anna"  "Erin" 
[26,] "Jim"   "Anna"  "Katie"
[27,] "Jim"   "Anna"  "Liz"  
[28,] "Jim"   "Erin"  "Anna" 
[29,] "Jim"   "Erin"  "Katie"
[30,] "Jim"   "Erin"  "Liz"  
[31,] "Jim"   "Katie" "Anna" 
[32,] "Jim"   "Katie" "Erin" 
[33,] "Jim"   "Katie" "Liz"  
[34,] "Jim"   "Liz"   "Anna" 
[35,] "Jim"   "Liz"   "Erin" 
[36,] "Jim"   "Liz"   "Katie"
[37,] "Katie" "Anna"  "Erin" 
[38,] "Katie" "Anna"  "Jim"  
[39,] "Katie" "Anna"  "Liz"  
[40,] "Katie" "Erin"  "Anna" 
[41,] "Katie" "Erin"  "Jim"  
[42,] "Katie" "Erin"  "Liz"  
[43,] "Katie" "Jim"   "Anna" 
[44,] "Katie" "Jim"   "Erin" 
[45,] "Katie" "Jim"   "Liz"  
[46,] "Katie" "Liz"   "Anna" 
[47,] "Katie" "Liz"   "Erin" 
[48,] "Katie" "Liz"   "Jim"  
[49,] "Liz"   "Anna"  "Erin" 
[50,] "Liz"   "Anna"  "Jim"  
[51,] "Liz"   "Anna"  "Katie"
[52,] "Liz"   "Erin"  "Anna" 
[53,] "Liz"   "Erin"  "Jim"  
[54,] "Liz"   "Erin"  "Katie"
[55,] "Liz"   "Jim"   "Anna" 
[56,] "Liz"   "Jim"   "Erin" 
[57,] "Liz"   "Jim"   "Katie"
[58,] "Liz"   "Katie" "Anna" 
[59,] "Liz"   "Katie" "Erin" 
[60,] "Liz"   "Katie" "Jim"  

If we want to simply compute the number of permutations (instead of listing them all out), we can nest the permutations() code inside the nrow() function, which counts the number of rows in a matrix or dataframe. The following code chunk computes \[_5P_3 = \frac{5!}{(5 - 3)!}\] and should return the value 60.

nrow(permutations(5, 3))
[1] 60

Tasks

Now that you’ve been introduced to some operations and functions in R, complete the following tasks for the Lab 02 assignment.

For Tasks 1 - 3, assume Adam, Bianca, Cam, Derek, Emilio, and Faith attend a gathering and are selected as the six finalists for 3 door prizes. Suppose names are drawn randomly from a hat.

Task 1

The six attendees are given seats at the front of the room before the drawing. How many different possible ways can the six people be seated in six seats?

factorial(6)
[1] 720

Task 2

The first prize is better than the second which is better than the third. How many possible sets of prize winners are possible if it matters who wins which prize (and nobody can receive more than one prize). Also produce these different sets with the NAMES of the finalists included (see the family names example above).

names <- c("lily", "pablo", "gibby", "brandon", "dakota","karstin")
permutations(6,3, names)
       [,1]      [,2]      [,3]     
  [1,] "brandon" "dakota"  "gibby"  
  [2,] "brandon" "dakota"  "karstin"
  [3,] "brandon" "dakota"  "lily"   
  [4,] "brandon" "dakota"  "pablo"  
  [5,] "brandon" "gibby"   "dakota" 
  [6,] "brandon" "gibby"   "karstin"
  [7,] "brandon" "gibby"   "lily"   
  [8,] "brandon" "gibby"   "pablo"  
  [9,] "brandon" "karstin" "dakota" 
 [10,] "brandon" "karstin" "gibby"  
 [11,] "brandon" "karstin" "lily"   
 [12,] "brandon" "karstin" "pablo"  
 [13,] "brandon" "lily"    "dakota" 
 [14,] "brandon" "lily"    "gibby"  
 [15,] "brandon" "lily"    "karstin"
 [16,] "brandon" "lily"    "pablo"  
 [17,] "brandon" "pablo"   "dakota" 
 [18,] "brandon" "pablo"   "gibby"  
 [19,] "brandon" "pablo"   "karstin"
 [20,] "brandon" "pablo"   "lily"   
 [21,] "dakota"  "brandon" "gibby"  
 [22,] "dakota"  "brandon" "karstin"
 [23,] "dakota"  "brandon" "lily"   
 [24,] "dakota"  "brandon" "pablo"  
 [25,] "dakota"  "gibby"   "brandon"
 [26,] "dakota"  "gibby"   "karstin"
 [27,] "dakota"  "gibby"   "lily"   
 [28,] "dakota"  "gibby"   "pablo"  
 [29,] "dakota"  "karstin" "brandon"
 [30,] "dakota"  "karstin" "gibby"  
 [31,] "dakota"  "karstin" "lily"   
 [32,] "dakota"  "karstin" "pablo"  
 [33,] "dakota"  "lily"    "brandon"
 [34,] "dakota"  "lily"    "gibby"  
 [35,] "dakota"  "lily"    "karstin"
 [36,] "dakota"  "lily"    "pablo"  
 [37,] "dakota"  "pablo"   "brandon"
 [38,] "dakota"  "pablo"   "gibby"  
 [39,] "dakota"  "pablo"   "karstin"
 [40,] "dakota"  "pablo"   "lily"   
 [41,] "gibby"   "brandon" "dakota" 
 [42,] "gibby"   "brandon" "karstin"
 [43,] "gibby"   "brandon" "lily"   
 [44,] "gibby"   "brandon" "pablo"  
 [45,] "gibby"   "dakota"  "brandon"
 [46,] "gibby"   "dakota"  "karstin"
 [47,] "gibby"   "dakota"  "lily"   
 [48,] "gibby"   "dakota"  "pablo"  
 [49,] "gibby"   "karstin" "brandon"
 [50,] "gibby"   "karstin" "dakota" 
 [51,] "gibby"   "karstin" "lily"   
 [52,] "gibby"   "karstin" "pablo"  
 [53,] "gibby"   "lily"    "brandon"
 [54,] "gibby"   "lily"    "dakota" 
 [55,] "gibby"   "lily"    "karstin"
 [56,] "gibby"   "lily"    "pablo"  
 [57,] "gibby"   "pablo"   "brandon"
 [58,] "gibby"   "pablo"   "dakota" 
 [59,] "gibby"   "pablo"   "karstin"
 [60,] "gibby"   "pablo"   "lily"   
 [61,] "karstin" "brandon" "dakota" 
 [62,] "karstin" "brandon" "gibby"  
 [63,] "karstin" "brandon" "lily"   
 [64,] "karstin" "brandon" "pablo"  
 [65,] "karstin" "dakota"  "brandon"
 [66,] "karstin" "dakota"  "gibby"  
 [67,] "karstin" "dakota"  "lily"   
 [68,] "karstin" "dakota"  "pablo"  
 [69,] "karstin" "gibby"   "brandon"
 [70,] "karstin" "gibby"   "dakota" 
 [71,] "karstin" "gibby"   "lily"   
 [72,] "karstin" "gibby"   "pablo"  
 [73,] "karstin" "lily"    "brandon"
 [74,] "karstin" "lily"    "dakota" 
 [75,] "karstin" "lily"    "gibby"  
 [76,] "karstin" "lily"    "pablo"  
 [77,] "karstin" "pablo"   "brandon"
 [78,] "karstin" "pablo"   "dakota" 
 [79,] "karstin" "pablo"   "gibby"  
 [80,] "karstin" "pablo"   "lily"   
 [81,] "lily"    "brandon" "dakota" 
 [82,] "lily"    "brandon" "gibby"  
 [83,] "lily"    "brandon" "karstin"
 [84,] "lily"    "brandon" "pablo"  
 [85,] "lily"    "dakota"  "brandon"
 [86,] "lily"    "dakota"  "gibby"  
 [87,] "lily"    "dakota"  "karstin"
 [88,] "lily"    "dakota"  "pablo"  
 [89,] "lily"    "gibby"   "brandon"
 [90,] "lily"    "gibby"   "dakota" 
 [91,] "lily"    "gibby"   "karstin"
 [92,] "lily"    "gibby"   "pablo"  
 [93,] "lily"    "karstin" "brandon"
 [94,] "lily"    "karstin" "dakota" 
 [95,] "lily"    "karstin" "gibby"  
 [96,] "lily"    "karstin" "pablo"  
 [97,] "lily"    "pablo"   "brandon"
 [98,] "lily"    "pablo"   "dakota" 
 [99,] "lily"    "pablo"   "gibby"  
[100,] "lily"    "pablo"   "karstin"
[101,] "pablo"   "brandon" "dakota" 
[102,] "pablo"   "brandon" "gibby"  
[103,] "pablo"   "brandon" "karstin"
[104,] "pablo"   "brandon" "lily"   
[105,] "pablo"   "dakota"  "brandon"
[106,] "pablo"   "dakota"  "gibby"  
[107,] "pablo"   "dakota"  "karstin"
[108,] "pablo"   "dakota"  "lily"   
[109,] "pablo"   "gibby"   "brandon"
[110,] "pablo"   "gibby"   "dakota" 
[111,] "pablo"   "gibby"   "karstin"
[112,] "pablo"   "gibby"   "lily"   
[113,] "pablo"   "karstin" "brandon"
[114,] "pablo"   "karstin" "dakota" 
[115,] "pablo"   "karstin" "gibby"  
[116,] "pablo"   "karstin" "lily"   
[117,] "pablo"   "lily"    "brandon"
[118,] "pablo"   "lily"    "dakota" 
[119,] "pablo"   "lily"    "gibby"  
[120,] "pablo"   "lily"    "karstin"

Task 3

All three prizes are the same, and nobody can win more than one. How many possible sets of winners are now possible if it doesn’t matter which prize a person earns. Again, also use R to produce the different possible sets of winners using their names.

names <- c("lily", "pablo", "gibby", "brandon", "dakota","karstin")
combinations(6, 3, names)
      [,1]      [,2]      [,3]     
 [1,] "brandon" "dakota"  "gibby"  
 [2,] "brandon" "dakota"  "karstin"
 [3,] "brandon" "dakota"  "lily"   
 [4,] "brandon" "dakota"  "pablo"  
 [5,] "brandon" "gibby"   "karstin"
 [6,] "brandon" "gibby"   "lily"   
 [7,] "brandon" "gibby"   "pablo"  
 [8,] "brandon" "karstin" "lily"   
 [9,] "brandon" "karstin" "pablo"  
[10,] "brandon" "lily"    "pablo"  
[11,] "dakota"  "gibby"   "karstin"
[12,] "dakota"  "gibby"   "lily"   
[13,] "dakota"  "gibby"   "pablo"  
[14,] "dakota"  "karstin" "lily"   
[15,] "dakota"  "karstin" "pablo"  
[16,] "dakota"  "lily"    "pablo"  
[17,] "gibby"   "karstin" "lily"   
[18,] "gibby"   "karstin" "pablo"  
[19,] "gibby"   "lily"    "pablo"  
[20,] "karstin" "lily"    "pablo"  

BONUS 1

Having to use nrow() around permutations() is a little cumbersome and computationally wasteful (generates a whole matrix only to collapse it down to one number by counting its rows). We can use R to write our own functions. The code below creates a function called perm_count, which takes the arguments n and k, and uses the permutation formula (involving factorials) to compute \(_nP_k\)

perm_count <- function(n, k){
  factorial(n)/(factorial(n - k))
}

Write a similar function called comb_count that computes the number of combinations. Note, your function should return the same values as the choose() function. Use your function to compute 64 choose 4.

comb_count <- function(n, k){
factorial(n)/((factorial(n - k)*(factorial(k))))
}
comb_count(64,4)
[1] 635376

BONUS 2 - EXTRA CHALLENGE

Write a function called pascals that takes in one argument n and returns a vector with the n + 1 coefficients of the \(n^{th}\) row of Pascal’s triangle. That is pascals(0) should return 1, pascals(3) should return 1 3 3 1, etc. Note, there are many ways to do this, but you can make use of existing R functions such as choose() and/or factorial().

pascals <- function(n,k) {
choose(n,n-1)
}
pascals(3)
[1] 3