在R中生成分层随机序列的最佳方法是什么?

时间:2016-11-26 22:37:51

标签: r

我想在R中创建一个训练计划,通过从大型数据框中包含的训练生成一系列训练(行是训练,3列包含锻炼名称,类别和持续时间的功能)。 '分类'取值A到N,每个类别的训练次数不等。我想按顺序生成序列如下: 1.从A类中抽取随机训练,然后从B,然后从C到N,开始序列。 2.通过重复(1)继续生成序列,每次绘制而不从A类到N类替换。 3.当绘制任何类别(例如A)的所有训练时,重新填充'该类别并开始绘图而无需再次更换。 4.继续,直到所有锻炼至少使用一次。 5.输出构建的序列,但保留每个训练的所有原始信息(即所有3列)(包括重复)。

感谢您对这个非常重要的问题的帮助:)

感谢Jim,您的样本数据集和您的回复。这是一个很好的代表性假数据集(为简单起见,实际类别少于实际):

set.seed(1)  
dat <- data.frame(workout = sample(1:200), category =     sample(c('A','B','C'),200,T))  

head(dat)  
#   workout category
# 1      25        C
# 2      14        C
# 3     191        C
# 4      88        C
# 5      73        B
# 6      34        B

但是,我应该指定我每天只需要一次锻炼,因此每个输出行代表锻炼计划中的一天。希望输出看起来像这样:

head(dat)  
#Day  workout  category  
#1    8        A    
#2    73       B  
#3    88       C  
#4    4        A  

1 个答案:

答案 0 :(得分:1)

dat <- data.frame(workout = sample(1:15), category = sample(c('A','B','C'),15,T))
dat
#   workout category
#1       14        A
#2        1        B
#3       11        A
#4        9        B
#5       13        A
#6       12        C
#7        6        B
#8        8        C
#9        3        C
#10      15        A
#11       4        C
#12       7        B
#13       5        A
#14      10        A
#15       2        B
cats <- list()
cats[[1]] <- which(dat$category=='A')
cats[[2]] <- which(dat$category=='B')
cats[[3]] <- which(dat$category=='C')
lens <- sapply(cats,length)
m <- max(lens)
days <- matrix(0,m,3)
for(i in 1:3){
    if(lens[i]==m) days[,i] <- sample(cats[[i]])
    else days[,i] <- c(sample(cats[[i]]),sample(cats[[i]],m-lens[i]))
}

然后适当重新排序的数据集是

    dat[c(t(days)),]
#     workout category
#13         5        A
#7          6        B
#6         12        C
#5         13        A
#2          1        B
#8          8        C
#14        10        A
#12         7        B
#11         4        C
#10        15        A
#4          9        B
#9          3        C
#1         14        A
#15         2        B
#11.1       4        C
#3         11        A
#2.1        1        B
#6.1       12        C

编辑:如果某些类别出现的次数是其他类别的两倍以上,则需要对上述内容进行一些修改,您应该使用下面的函数

reorder <- function(dat){
    if(!('category' %in% names(dat))) return('No column named category')
    categories <- sort(unique(dat$category))
    N <- length(categories)
    fun <- function(cat) which(dat$category==cat)
    cats <- lapply(categories,fun)
    lens <- sapply(cats,length)
    m <- max(lens)
    days <- matrix(0, m, N)
    for(i in 1:N){
        ratio <- m/lens[i]
        out <- sample(cats[[i]])
        if(ratio > 1){
            if(ratio > 2) for(j in 2:floor(ratio)) out <- c(out, sample(cats[[i]]))
            out <- c(out, sample(cats[[i]], m - length(out)))
        }
        days[,i] <- out
    }
    return(dat[c(t(days)),])
}