Calculando el rango de percentil en R [cerrado]

18

¿Cómo puedo agregar una nueva variable al marco de datos que será el rango de percentil de una de las variables? Puedo hacer esto en Excel fácilmente, pero realmente quiero hacerlo en R.

Gracias

usuario333
fuente

Respuestas:

27

Dado un vector de valores de datos sin procesar, una función simple podría verse como

perc.rank <- function(x, xo)  length(x[x <= xo])/length(x)*100

donde x0es el valor para el que queremos el rango de percentil, dado el vector x, como se sugiere en R-bloggers .

Sin embargo, podría fácilmente ser vectorizado como

perc.rank <- function(x) trunc(rank(x))/length(x)

que tiene la ventaja de no tener que pasar cada valor. Entonces, aquí hay un ejemplo de uso:

my.df <- data.frame(x=rnorm(200))
my.df <- within(my.df, xr <- perc.rank(x))
chl
fuente
3
1. Su función no imita la función de Excel percentrank, que es buena (+1) ya que esta última da resultados "extraños" (vea mi comparación ). 2. No nombraría el marco de datos df, porque dfes una función R (la densidad de la distribución F, ver ?df).
Bernd Weiss
1
@Bernd Gracias. (1) Hay algunas funciones integradas para calcular PR en varios paquetes de psicometría. Creo que tomé este del CTTpaquete hace un tiempo. No verifiqué con Excel porque no lo tengo / no lo uso. Acerca de (2) ¡Parece que siempre me olvido de esto! Vamos con my.*(Perl way) :-)
chl
@chl ¿por qué es truncnecesario? Parece que el rango siempre devolverá un número entero de todos modos.
Tyler Rinker
1
@Tyler Nope. En caso de que haya vínculos, el valor rank()predeterminado es tomar el promedio de los valores vinculados (cf. ties.method = c("average",...)).
chl
8

Si se llama a su data.frame original y se llama a dfrla variable de interés myvar, puede usar dfr$myrank<-rank(dfr$myvar)para rangos normales, odfr$myrank<-rank(dfr$myvar)/length(myvar) para rangos de percentiles.

Oh bien. Si realmente lo quieres a la manera de Excel (puede que no sea la solución más simple, pero me divertí usando nuevas funciones (para mí) y evitando bucles):

percentilerank<-function(x){
  rx<-rle(sort(x))
  smaller<-cumsum(c(0, rx$lengths))[seq(length(rx$lengths))]
  larger<-rev(cumsum(c(0, rev(rx$lengths))))[-1]
  rxpr<-smaller/(smaller+larger)
  rxpr[match(x, rx$values)]
}

así que ahora puedes usar dfr$myrank<-percentilerank(dfr$myvar)

HTH.

Nick Sabbe
fuente
1 - (rango / tamaño) le da lo mismo que Excel percentilerank
user333
Obtuve esto de office.microsoft.com
Nick Sabbe
Un editor anónimo (intentado) intentó agregar el siguiente comentario: "Buena función pero a veces, desafortunadamente, el RLE puede devolver el vector de length < length(dfr$myvar)".
gung - Restablece a Monica
1

Un problema con la respuesta presentada es que no funcionará correctamente cuando tenga NA.

En este caso, otra posibilidad (inspirada en la función de chl ♦) es:

perc.rank <- function(x) trunc(rank(x,na.last = NA))/sum(!is.na(x))
quant <- function (x, p.ile) {
      x[which.min(x = abs(perc.rank(x-(p.ile/100))))]
}

Aquí, x es el vector de valores, y p.ile es el percentil por rango. El percentil 2.5 por rango de coef.mat (arbitrario) puede calcularse mediante:

quant(coef.mat[,3], 2.5)  
[1] 0.00025  

o como una sola función:

quant <- function (x, p.ile) {
   perc.rank <- trunc(rank(x,na.last = NA))/sum(!is.na(x))
   x = na.omit(x)
   x[which.min(x = abs(perc.rank(x-(p.ile/100))))]
}
Farshad
fuente