Obliczanie rangi percentylowej w R [zamknięte]

18

Jak mogę dodać nową zmienną do ramki danych, która będzie percentylową rangą jednej ze zmiennych? Mogę to łatwo zrobić w programie Excel, ale naprawdę chcę to zrobić w R.

Dzięki

użytkownik333
źródło

Odpowiedzi:

27

Biorąc pod uwagę wektor wartości surowych danych, może wyglądać prosta funkcja

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

gdzie x0jest wartość, dla której chcemy rangę percentylową, biorąc pod uwagę wektor x, jak sugerują R-blogerzy .

Można go jednak łatwo wektoryzować jako

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

co ma tę zaletę, że nie trzeba przekazywać każdej wartości. Oto przykład użycia:

my.df <- data.frame(x=rnorm(200))
my.df <- within(my.df, xr <- perc.rank(x))
chl
źródło
3
1. Twoja funkcja nie naśladuje funkcji Excela percentrank, co jest dobre (+1), ponieważ ta ostatnia daje „dziwne” wyniki (patrz moje porównanie ). 2. Nie nazwałbym ramki danych df, ponieważ dfjest to funkcja R (gęstość rozkładu F, patrz ?df).
Bernd Weiss,
1
@Bernd Thanks. (1) Istnieje kilka wbudowanych funkcji do obliczania PR w różnych pakietach psychometrii. Myślę, że CTTjakiś czas temu złapałem ten z paczki. Nie sprawdziłem programu Excel, ponieważ go nie mam / nie używam. O (2) Wydaje mi się, że zawsze o tym zapominam! Chodźmy z my.*(sposób Perla) :-)
chl
@chl dlaczego jest truncwymagany? Wygląda na to, że i tak ranga zawsze zwróci liczbę całkowitą.
Tyler Rinker,
1
@Tyler Nope. W przypadku powiązań rank()domyślnie przyjmuje się średnią z powiązanych wartości (por ties.method = c("average",...).).
chl
8

Jeśli twoja oryginalna data.frame jest wywoływana dfri wywoływana jest zmienna będąca przedmiotem zainteresowania myvar, możesz użyć dfr$myrank<-rank(dfr$myvar)dla normalnych rang lub dfr$myrank<-rank(dfr$myvar)/length(myvar)rang percentylowych.

No cóż. Jeśli naprawdę chcesz to w Excelu (może nie jest to najprostsze rozwiązanie, ale dobrze się bawiłem, używając nowych (dla mnie) funkcji i unikając pętli):

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)]
}

więc teraz możesz użyć dfr$myrank<-percentilerank(dfr$myvar)

HTH.

Nick Sabbe
źródło
1 - (ranga / rozmiar) daje to samo, co excel percentilerank
user333
Dostałem to z office.microsoft.com
Nick Sabbe,
Anonimowy (usiłowany) edytor próbował dodać następujący komentarz: „Fajna funkcja, ale czasami, niestety, RLE może zwrócić wektor length < length(dfr$myvar)”.
gung - Przywróć Monikę
1

Problem z przedstawioną odpowiedzią polega na tym, że nie będzie ona działać poprawnie, gdy masz NA.

W tym przypadku inną możliwością (inspirowaną funkcją chl ♦) jest:

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))))]
}

Tutaj x jest wektorem wartości, a p.ile jest percentylem według rangi. 2,5 percentyl według rangi (arbitralnej) wartości współczynnika może być obliczony przez:

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

lub jako pojedyncza funkcja:

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
źródło