dividere una variabile continua in gruppi di dimensioni uguali

Devo dividere / dividere una variabile continua in 3 gruppi di uguale dimensione.

Esempio di cornice dati

das <- data.frame(anim=1:15, wt=c(181,179,180.5,201,201.5,245,246.4, 189.3,301,354,369,205,199,394,231.3)) 

Dopo essere stato tagliato (in base al valore di wt ), avrei bisogno di avere le 3 classi sotto la nuova variabile wt2 questo modo:

 > das anim wt wt2 1 1 181.0 1 2 2 179.0 1 3 3 180.5 1 4 4 201.0 2 5 5 201.5 2 6 6 245.0 2 7 7 246.4 3 8 8 189.3 1 9 9 301.0 3 10 10 354.0 3 11 11 369.0 3 12 12 205.0 2 13 13 199.0 1 14 14 394.0 3 15 15 231.3 2 

Questo sarebbe applicato a un grande set di dati

prova questo:

 split(das, cut(das$anim, 3)) 

se si desidera dividere in base al valore di wt , quindi

 library(Hmisc) # cut2 split(das, cut2(das$wt, g=3)) 

comunque, puoi farlo combinando cut , cut2 e split .

AGGIORNATO

se vuoi un indice di gruppo come colonna aggiuntiva, allora

 das$group <- cut(das$anim, 3) 

se la colonna dovrebbe essere indice come 1, 2, ..., allora

 das$group <- as.numeric(cut(das$anim, 3)) 

AGGIORNATO DI NUOVO

prova questo:

 > das$wt2 <- as.numeric(cut2(das$wt, g=3)) > das anim wt wt2 1 1 181.0 1 2 2 179.0 1 3 3 180.5 1 4 4 201.0 2 5 5 201.5 2 6 6 245.0 2 7 7 246.4 3 8 8 189.3 1 9 9 301.0 3 10 10 354.0 3 11 11 369.0 3 12 12 205.0 2 13 13 199.0 1 14 14 394.0 3 15 15 231.3 2 

Oppure vedi cut_number dal pacchetto ggplot2 , ad es

 das$wt_2 <- as.numeric(cut_number(das$wt,3)) 

Si noti che cut(...,3) divide l'intervallo dei dati originali in tre intervalli di uguale lunghezza; non risulta necessariamente lo stesso numero di osservazioni per gruppo se i dati sono distribuiti in modo non uniforms (è ansible replicare ciò che cut_number utilizza in modo appropriato il quantile , ma è una buona funzione di convenienza). D'altra parte, Hmisc::cut2() usando l'argomento g= diviso per quantili, quindi è più o meno equivalente a ggplot2::cut_number . Avrei potuto pensare che qualcosa come cut_number avrebbe fatto il suo ingresso in dplyr da così lontano, ma per quanto posso dire che non è così .

Alternativa senza usare cut2.

 das$wt2 <- as.factor( as.numeric( cut(das$wt,3))) 

o

 das$wt2 <- as.factor( cut(das$wt,3, labels=F)) 

ntile di dplyr ora lo fa, ma si comporta stranamente con NA .

Ho usato un codice simile nella seguente funzione che funziona in R base e fa l’equivalente della soluzione cut2 sopra:

 ntile_ <- function(x, n) { b <- x[!is.na(x)] q <- floor((n * (rank(b, ties.method = "first") - 1)/length(b)) + 1) d <- rep(NA, length(x)) d[!is.na(x)] <- q return(d) } 

Ecco un’altra soluzione che utilizza la funzione bin_data() dal pacchetto mltools .

 library(mltools) # Resulting bins have an equal number of observations in each group das[, "wt2"] <- bin_data(das$wt, bins=3, binType = "quantile") # Resulting bins are equally spaced from min to max das[, "wt3"] <- bin_data(das$wt, bins=3, binType = "explicit") # Or if you'd rather define the bins yourself das[, "wt4"] <- bin_data(das$wt, bins=c(-Inf, 250, 322, Inf), binType = "explicit") das anim wt wt2 wt3 wt4 1 1 181.0 [179, 200.333333333333) [179, 250.666666666667) [-Inf, 250) 2 2 179.0 [179, 200.333333333333) [179, 250.666666666667) [-Inf, 250) 3 3 180.5 [179, 200.333333333333) [179, 250.666666666667) [-Inf, 250) 4 4 201.0 [200.333333333333, 245.466666666667) [179, 250.666666666667) [-Inf, 250) 5 5 201.5 [200.333333333333, 245.466666666667) [179, 250.666666666667) [-Inf, 250) 6 6 245.0 [200.333333333333, 245.466666666667) [179, 250.666666666667) [-Inf, 250) 7 7 246.4 [245.466666666667, 394] [179, 250.666666666667) [-Inf, 250) 8 8 189.3 [179, 200.333333333333) [179, 250.666666666667) [-Inf, 250) 9 9 301.0 [245.466666666667, 394] [250.666666666667, 322.333333333333) [250, 322) 10 10 354.0 [245.466666666667, 394] [322.333333333333, 394] [322, Inf] 11 11 369.0 [245.466666666667, 394] [322.333333333333, 394] [322, Inf] 12 12 205.0 [200.333333333333, 245.466666666667) [179, 250.666666666667) [-Inf, 250) 13 13 199.0 [179, 200.333333333333) [179, 250.666666666667) [-Inf, 250) 14 14 394.0 [245.466666666667, 394] [322.333333333333, 394] [322, Inf] 15 15 231.3 [200.333333333333, 245.466666666667) [179, 250.666666666667) [-Inf, 250) 

Senza alcun pacchetto aggiuntivo, 3 è il numero di gruppi:

 > findInterval(das$wt, unique(quantile(das$wt, seq(0, 1, length.out = 3 + 1))), rightmost.closed = TRUE) [1] 1 1 1 2 2 2 3 1 3 3 3 2 1 3 2 

È ansible accelerare il calcolo quantile utilizzando un campione rappresentativo dei valori di interesse. Controlla la documentazione della funzione FindInterval .