R offers you several ways to randomly choose a number or to randomly select a sample from a larger group, or to randomly allocate a subject to one of two or more groups.

A simple random number generator

R can generate random numbers from many distributions. For a simple random number generator, runif() is probably the most useful. It will generate a vector of one or more numbers where each one is equally likely to be anywhere between zero and one

For one number:

runif(1)
## [1] 0.2194309

For three numbers:

runif(3)
## [1] 0.01393749 0.03497450 0.39715232

The numbers generated can be made to be spread between any minimum and maximum value you choose:

runif(5,min=2,max=4)
## [1] 3.814560 3.114899 3.130364 3.381134 3.164550

We can use this command to allocate a group of replicates between two groups. Here is one way to do it

n<-20 # suppose we have 20 replicates in all
treatment<-ifelse(runif(n)<0.5,"Control","Treatment")
treatment
##  [1] "Treatment" "Treatment" "Treatment" "Treatment" "Treatment" "Treatment"
##  [7] "Treatment" "Treatment" "Control"   "Control"   "Treatment" "Treatment"
## [13] "Treatment" "Control"   "Treatment" "Control"   "Treatment" "Treatment"
## [19] "Control"   "Control"

But this way of doing it does not necessarily give us two equally sized groups.

Sampling without replacement

To get that easily, we can use the sample() command:

The default of sample() is to randomly shuffle the elements of a vector, while keeping all the numerical values intact:

Let us create a sequence y of integers from 1 to 10

y<-1:10
y
##  [1]  1  2  3  4  5  6  7  8  9 10

And here are two shufflings of y:

sample(y)
##  [1]  3  7  6  2  1  9  4  5  8 10
sample(y)
##  [1]  8  2 10  7  3  1  6  9  4  5

All the original numbers of y appear once in the output. This is called sampling without replacement. It is like putting numbered balls into a bag and then taking them out, one by one, without putting any back before taking the next one, until they have all been picked.

If we wanted,say, 5 randomly chosen elements from y (like taking 5 randomly chosen balls from a bag of 10 of them, without replacement) we would type

sample(y,5)
## [1] 3 2 7 5 1

Allocating replicates equally and randomly between treatments

Suppose we have 20 replicates, number 1 to 20

We can randomly select 10 of them like this:

sample(1:20,10,replace=FALSE)
##  [1]  7  9 14  6 13 16  5  4 11  1

These could be the 10 replicates we allocate to the Control group. The other 10 would go into the treatment group.

This command is working just as if we had 20 balls in a bag, numbered 1 to 20, and randomly picked 10 of them, without putting the balls back after they have been picked (so that no ball gets picked twice).

If we want a nice printout that lists our replicates in order, showing their allocation to Control or Treatment, we can do this:

n<-20 # how many replicates altogether?
allocation<-tibble(id=1:n,selector=sample(id,n,replace=FALSE)) %>%
  mutate(Level=ifelse(selector<=n/2,"Control","Treatment")) %>%
  dplyr::select(id,Level)

head(allocation)

If we want a listing of all the plants allocated to each group, arranged by group, we can do this:

library(tidyverse)
n<-20 # how many replicates altogether?
allocation<-tibble(id=1:n,selector=sample(id,n,replace=FALSE)) %>%
  mutate(Level=ifelse(selector<=n/2,"Control","Treatment")) %>%
  dplyr::select(id,Level)

Control<-filter(allocation,Level=="Control") %>%
  dplyr::select(id)
print("ids of Control group")
## [1] "ids of Control group"
pull(Control)
##  [1]  2  3  4  7  9 12 13 14 15 16
Treatment<-filter(allocation,Level=="Treatment") %>%
  dplyr::select(id)
print("ids of Treatment group")
## [1] "ids of Treatment group"
pull(Treatment)
##  [1]  1  5  6  8 10 11 17 18 19 20

One way, n-treatment designs

Suppose we had 40 replicates and wanted to divide them randomly between 4 treatment groups, including a control

n<-40
x<-sample(1:n)
levels<-5
split(x, x%%levels)
## $`0`
## [1] 35 25 20 15 40 30 10  5
## 
## $`1`
## [1] 26 36 21  6 11 16 31  1
## 
## $`2`
## [1] 37 27 17  2 12 32  7 22
## 
## $`3`
## [1] 23 28 13 18  8  3 33 38
## 
## $`4`
## [1]  4 39 24 19 29 34 14  9