In this practical we will write a simple function that simulates rolling one or more dice.

The function sample()

The function sample allows us to draw values from a given set of values, with or without replacement.

It has arguments

  • x: a vector of values to draw from
  • size: the number of values to draw
  • replace: can we choose the same element of x multiple times?
  • prob: a vector of probability weights (by default all elements of x have equal probability to be drawn)

One die

Task 1

Write the syntax to simulate a single role of a die using the function sample() (for now, just the syntax to do this once, no need to write a custom function yet).

You need to specify the arguments x and size.

Solution 1

We need to specify the vector of possible outcomes of the die, and the size of the sample:

sample(1:6, size = 1)
## [1] 4

Task 2

Turn the syntax from the previous task into a function.

The general form of a function is
<function name> <- function( <arguments> ) {
  <function body>
}

Solution 2

We use the exact syntax from the previous solution as our function body. Since our function does not need any input (it will always do the same thing) the function does not need any arguments.

die <- function() {
  sample(1:6, size = 1)
}

die()
## [1] 3
die()
## [1] 6
die()
## [1] 6

Multiple dice

Task 1

Take another look at the description of the function sample(). How would you need to change the syntax from Task 1 from above to simulate rolling two dice?

You need to change what is passed to the argument size and you need to specify the argument replace.

Solution 1

When we role multiple dice, it could be that they show the same number, i.e., we need to sample with replacement from the possible outcome of a die (replace = TRUE).

sample(1:6, size = 2, replace = TRUE)
## [1] 1 4

Task 2

  • Write another function that simulates rolling multiple dice.
  • Write the function so that the number of dice is flexible.
This new function needs to have an argument, which then is passed to sample().

Solution 2

To be able to change the number of dice we need to write a function that has this number as an argument. We could, for example, call this argument n.

dice <- function(n) {
  sample(1:6, size = n, replace = TRUE)
}

We can now simulate rolling different numbers of dice:

dice(2)
## [1] 3 4
dice(1)
## [1] 5
dice(10)
##  [1] 3 6 2 4 5 6 2 3 4 5

Task 3

  • What happens when you use the function dice() without specifying the argument n?
  • Do you know or can you guess why that happens?

Solution 3

dice()
## [1] 6 5 1 6 2 3

By default, the function dice() will role 6 dice.

This is due to the behaviour of the function sample(). In the help file for sample() (run ?sample) we can read in the section Details:

For sample the default for size is the number of items inferred from the first argument, so that sample(x) generates a random permutation of the elements of x (or 1:x).

Usually, when no default value is set for a function argument, not specifying the argument will result in an error message.

For example, the function rnorm() does not have a default value for the sample size n (but it has defaults for the other arguments mean and sd) and so we get the following error:

rnorm()
## Error in rnorm(): argument "n" is missing, with no default

This does not happen in sample() because inside the definition of the function there is a piece of syntax that sets size to length(x) when it is missing.

is lazy and only “checks” what the value of n is when it actually needs it. This only happens inside sample(), where there is first a check if n was set and instructions to set it to the length of x instead.

What can we learn from this?

  • Read the help files!
  • Think about / try what will happen if “wrong” input is given to your function!

Task 4

Re-write the function dice() so that by default only one die is used.

Solution 4

We need to set a default value for the argument n:

dice <- function(n = 1) {
  sample(1:6, size = n, replace = TRUE)
}

Now, when we call dice() without specifying n, it will return a single number:

dice()
## [1] 3