РЕДАКТИРОВАТЬ: учитывая вашу реальную цель, почему бы вам просто не сделать (исправлено):
EqualFreq2 <- function(x,n){
nx <- length(x)
nrepl <- floor(nx/n)
nplus <- sample(1:n,nx - nrepl*n)
nrep <- rep(nrepl,n)
nrep[nplus] <- nrepl+1
x[order(x)] <- rep(seq.int(n),nrep)
x
}
Возвращает вектор с индикаторами, для которых они предназначены.Но так как некоторые значения могут присутствовать в обеих ячейках, вы не можете определить пределы ячейки.Но вы можете сделать:
x <- rpois(50,5)
y <- EqualFreq2(x,15)
table(y)
split(x,y)
Оригинальный ответ:
Вы можете просто использовать cut()
для этого:
EqualFreq <-function(x,n,include.lowest=TRUE,...){
nx <- length(x)
id <- round(c(1,(1:(n-1))*(nx/n),nx))
breaks <- sort(x)[id]
if( sum(duplicated(breaks))>0 stop("n is too large.")
cut(x,breaks,include.lowest=include.lowest,...)
}
Что дает:
set.seed(12345)
x <- rnorm(50)
table(EqualFreq(x,5))
[-2.38,-0.886] (-0.886,-0.116] (-0.116,0.586] (0.586,0.937] (0.937,2.2]
10 10 10 10 10
x <- rpois(50,5)
table(EqualFreq(x,5))
[1,3] (3,5] (5,6] (6,7] (7,11]
10 13 11 6 10
Как вы видите, для дискретных данных в большинстве случаев оптимальное равное объединение является довольно невозможным, но этот метод дает вам наилучшее возможное объединение.