lineas - recodificar variables en r
dividir una variable continua en grupos de igual tamaƱo (6)
Necesito dividir / dividir una variable continua en 3 grupos de igual tamaño.
Marco de datos de ejemplo
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))
Después de ser cortado (de acuerdo con el valor de wt
), necesitaría tener las 3 clases bajo la nueva variable wt2
como esta:
> 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
Esto se aplicaría a un gran conjunto de datos
Alternativa sin usar cut2.
das$wt2 <- as.factor( as.numeric( cut(das$wt,3)))
o
das$wt2 <- as.factor( cut(das$wt,3, labels=F))
Aquí hay otra solución que usa la función bin_data()
del paquete 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)
O vea cut_number
del paquete ggplot2
, por ejemplo
das$wt_2 <- as.numeric(cut_number(das$wt,3))
Tenga en cuenta que cut(...,3)
divide el rango de los datos originales en tres intervalos de igual longitud; no necesariamente da como resultado el mismo número de observaciones por grupo si los datos están distribuidos de manera desigual (puede replicar lo que cut_number
hace utilizando quantile
apropiada, pero es una buena función de conveniencia). Por otro lado, Hmisc::cut2()
utilizando el argumento g=
divide por cuantiles, por lo que es más o menos equivalente a ggplot2::cut_number
. Podría haber pensado que algo así como cut_number
hubiera llegado a dplyr
hasta ahora, pero hasta donde sé, no ha sido así .
Sin ningún paquete adicional, 3 es la cantidad de grupos:
> 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
Puede acelerar el cálculo de cuantiles utilizando una muestra representativa de los valores de interés. Verifique la documentación de la función FindInterval
.
prueba esto:
split(das, cut(das$anim, 3))
si quieres dividir en función del valor de wt
, entonces
library(Hmisc) # cut2
split(das, cut2(das$wt, g=3))
de todos modos, puedes hacer eso combinando cut
, cut2
y split
.
ACTUALIZADO
si desea un índice de grupo como una columna adicional, entonces
das$group <- cut(das$anim, 3)
si la columna debe ser índice como 1, 2, ..., entonces
das$group <- as.numeric(cut(das$anim, 3))
ACTUALIZADO OTRA VEZ
prueba esto:
> 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
ntile
de dplyr
ahora hace esto pero se comporta de forma extraña con NA
.
He utilizado un código similar en la siguiente función que funciona en la base R y hace el equivalente de la solución cut2
anterior:
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)
}