Questo si dividerà in modo diverso a quello che hai, ma è ancora abbastanza una struttura bella lista penso:
chunk.2 <- function(x, n, force.number.of.groups = TRUE, len = length(x), groups = trunc(len/n), overflow = len%%n) {
if(force.number.of.groups) {
f1 <- as.character(sort(rep(1:n, groups)))
f <- as.character(c(f1, rep(n, overflow)))
} else {
f1 <- as.character(sort(rep(1:groups, n)))
f <- as.character(c(f1, rep("overflow", overflow)))
}
g <- split(x, f)
if(force.number.of.groups) {
g.names <- names(g)
g.names.ordered <- as.character(sort(as.numeric(g.names)))
} else {
g.names <- names(g[-length(g)])
g.names.ordered <- as.character(sort(as.numeric(g.names)))
g.names.ordered <- c(g.names.ordered, "overflow")
}
return(g[g.names.ordered])
}
Quale vi darà la seguente, a seconda di come lo vuoi formattato:
> x <- 1:10; n <- 3
> chunk.2(x, n, force.number.of.groups = FALSE)
$`1`
[1] 1 2 3
$`2`
[1] 4 5 6
$`3`
[1] 7 8 9
$overflow
[1] 10
> chunk.2(x, n, force.number.of.groups = TRUE)
$`1`
[1] 1 2 3
$`2`
[1] 4 5 6
$`3`
[1] 7 8 9 10
Esecuzione di un paio di tempi che utilizzano queste impostazioni:
set.seed(42)
x <- rnorm(1:1e7)
n <- 3
Poi abbiamo i seguenti risultati:
> system.time(chunk(x, n)) # your function
user system elapsed
29.500 0.620 30.125
> system.time(chunk.2(x, n, force.number.of.groups = TRUE))
user system elapsed
5.360 0.300 5.663
EDIT: Cambiare da as.factor() per as.character() nella mia funzione ha reso due volte più veloce.
Sì, è molto chiaro che quello che si ottiene è la soluzione a "n pezzi di uguale dimensione". Ma forse questo ti porta anche lì: x <- 1:10; n <- 3; split (x, cut (x, n, labels = FALSE)) – mdsumner
sia la soluzione nella domanda, sia la soluzione nel commento precedente non sono corretti, in quanto potrebbero non funzionare, se il vettore ha voci ripetute. Prova questo: > foo <- c (rep (1, 12), rep (2,3), rep (3,3)) [1] 1 1 1 1 1 1 1 1 1 1 1 2 2 2 3 3 3 > pezzo (foo, 2) (dà risultato sbagliato) > chunk (foo, 3) (anche sbagliato) – mathheadinclouds
(continua commento precedente) perché? rank (x) non deve essere un numero intero > rank (c (1,1,2,3)) [1] 1,5 1,5 3,0 4,0 ecco perché il metodo nella domanda fallisce. questo funziona (grazie a Harlan in basso) > chunk2 <- function (x, n) split (x, cut (seq_along (x), n, labels = FALSE)) – mathheadinclouds