Random sampling of a dataset into training and test datasets

When you’re building a model, you generally have a dataset to train on. When evaluating the model later, you should be using a different dataset. Google’s dev crash course gives more information here. An easy way to have two datasets is to split it, and R has a way of doing that easily. Say you have the dataframe below:
> df
# A tibble: 20 x 3
Sample cat1 cat2
<chr> <chr> <chr>
1 sample1 A X
2 sample2 A X
3 sample3 A X
4 sample4 A X
5 sample5 A X
6 sample6 A Y
7 sample7 A Y
8 sample8 A Y
9 sample9 A Y
10 sample10 A Y
11 sample11 B X
12 sample12 B X
13 sample13 B X
14 sample14 B X
15 sample15 B X
16 sample16 B Y
17 sample17 B Y
18 sample18 B Y
19 sample19 B Y
20 sample20 B Y
The following code splits the data by column cat1.
First, it loads the required libraries for processing.
Starting with dataframe df, dplyr groups the data by the column cat1, and passes the result to slice_sample().
slice_sample() takes each group and grabs 80% of each group and stores it in trainingDataset.
Note: If you are following this tutorial exactly, don’t expect to get the exact same results, because slice_sample() chooses rows of df randomly.
library(dplyr)
library(sampling)
trainingDataset <- df %>% group_by(cat1) %>% slice_sample(prop = 0.8)
Sometimes, the output looks like below, where this trainingDataset represents 80% of each group in cat1, but not in cat2.
> trainingDataset
# A tibble: 16 x 3
# Groups: cat1 [2]
Sample cat1 cat2
<chr> <chr> <chr>
1 sample8 A Y
2 sample6 A Y
3 sample5 A X
4 sample9 A Y
5 sample7 A Y
6 sample1 A X
7 sample10 A Y
8 sample2 A X
9 sample19 B Y
10 sample20 B Y
11 sample14 B X
12 sample11 B X
13 sample13 B X
14 sample17 B Y
15 sample16 B Y
16 sample18 B Y
Now, we need to split the data by two categories.
Adding column names to the group_by() function allows us to do so.
multiCatDataset <-df %>% group_by(cat1, cat2) %>% slice_sample(prop = 0.8)
Now, the data looks like so:
> multiCatDataset
# A tibble: 16 x 3
# Groups: cat1, cat2 [4]
Sample cat1 cat2
<chr> <chr> <chr>
1 sample3 A X
2 sample1 A X
3 sample5 A X
4 sample4 A X
5 sample10 A Y
6 sample9 A Y
7 sample6 A Y
8 sample8 A Y
9 sample13 B X
10 sample15 B X
11 sample11 B X
12 sample12 B X
13 sample19 B Y
14 sample17 B Y
15 sample18 B Y
16 sample20 B Y
Now, we need to grab the samples from df that are not in our training dataset:
testDataset <- subset(df, !(Sample %in% trainingDataset$Sample))
This produces the correct final result.
> testDataset
# A tibble: 4 x 3
Sample cat1 cat2
<chr> <chr> <chr>
1 sample3 A X
2 sample4 A X
3 sample12 B X
4 sample15 B X
This can be used multiple times, to separate a dataset into as many as are needed for your analysis, for example: training, cross-validation and test datasets.