Alex Rivera | Logout

Partitioning data set in r based on multiple classes of observations

Asked 2012-11-23T22:44:38.530
15

I'm trying to partition a data set that I have in R, 2/3 for training and 1/3 for testing. I have one classification variable, and seven numerical variables. Each observation is classified as either A, B, C, or D.

For simplicity's sake, let's say that the classification variable, cl, is A for the first 100 observations, B for observations 101 to 200, C till 300, and D till 400. I'm trying to get a partition that has 2/3 of the observations for each of A, B, C, and D (as opposed to simply getting 2/3 of the observations for the entire data set since it will likely not have equal amounts of each classification).

When I try to sample from a subset of the data, such as sample(subset(data, cl=='A')), the columns are reordered instead of the rows.

To summarize, my goal is to have 67 random observations from each of A, B, C, and D as my training data, and store the remaining 33 observations for each of A, B, C, and D as testing data. I have found a very similar question to mine, but it did not factor in multiple variables.

Edit
Report

1 Answer

1

Bumped into this issue while constructing my own function for partitioning data for cross-validation with multiple factors for stratification. You could construct such datasets by dividing the data into 3 (or N) equally sized portions while dividing observations within each strata equally to the portions, and then selecting one third as the test set and then combine rest as the training set. I would handle such as list elements in R.

Here is a function that I built using the base package that supports multiple stratification factors, indicated as the column numbers or column names of fields that you wish to have as strata (mtcars dataset example). I think it is rather similar in functionality to ddply, with the exception that you can also use column numbers and that the resulting subsets are given inside a list:

# Function that partitions data into a number of equally (or almost-equally) sized bins that do not overlap, and returns the data bins as a list
# Useful for cross validation
partition_data <- function(
    # Data frame to partition (default example: mtcars data, assuming rows correspond to observations)
    dat = mtcars,
    # Number of equally sized bins to partition to (default here: 2 bins)
    bins = 2,
    # Stratification element, homogeneous subpopulations according to a column that should be subsampled,
    # Observations within a substrata are divided equally to the partitioned bins
    stratum = NA
){
    # Total number of observations
    nobs <- dim(dat)[1]
    # Allocation vector, to be used for randomly distributing the samples to the bins
    loc <- rep(1:bins, times=ceiling(nobs/bins))[1:nobs]


    # If the dataset is stratified, each subpopulation is distributed equally to the bins, otherwise the whole population is the "subpopulation"
    if(missing(stratum)){
        pops <- list(sample(1:dim(dat)[1]))
    }else{
        uniqs <- na.omit(as.matrix(unique(dat[,s
answered 2013-05-29T03:22:38.630

Your Answer