这是一个丑陋但实用的解决方案。我为奇怪、复杂的子集道歉,但不幸的是 by() 以一种非常奇怪的方式存储它的数据。
mysamp <- function(dat){
samp <- runif(length(dat)) #get 12 random numbers
samp <- ceiling(samp*12) #standardize between 1 and 12
return(samp)
}
这就是您将用来将总体划分为 12 个样本的函数。现在说'zz'是你的数据集:
cust <- c(101, 101, 102, 105, 107)
prod <- c(4004, 2000, 3000, 3000, 4004)
life <- c('A', 'B', 'B', 'B', 'A')
zz <- data.frame(cust, prod, life)
prodlife <- paste0(zz$prod, zz$life)
zz <- data.frame(zz, prodlife)
给你
> zz
cust prod life prodlife
1 101 4004 A 4004A
2 101 2000 B 2000B
3 102 3000 B 3000B
4 105 3000 B 3000B
5 107 4004 A 4004A
然后,您需要创建一列 0 来放入 cycle.id(在我的示例中我将其称为“cyc”)。像添加 zz$prodlife 一样将其附加到 data.frame。然后您可以使用这些语句进行采样并将样本分配给列:
cycle <- by(newzz$cust, newzz$prodlife, mysamp)
for(i in 1:length(cycle)){
for(j in 1: length(cycle[i][[1]])){
zz$cyc[zz$prodlife == names(cycle)[i]][j] <- cycle[i][[1]][j]
}
}
by() 语句在那里完成所有工作,而可怕的 for 循环只是将采样值分配给正确的位置。因为“by”类的子集不方便,所以我想不出更有效的方法来完成这项任务,但也许其他人可以......?无论如何,这给了我:
> zz
cust prod life prodlife cyc
1 101 4004 A 4004A 6
2 101 2000 B 2000B 5
3 102 3000 B 3000B 7
4 105 3000 B 3000B 8
5 107 4004 A 4004A 1
当然,这个例子太小了,无法判断样本是否正确分层,但这应该可行。快乐编码!