Services & Resources / Wolfram Forums
-----
 /
MathGroup Archive
2000
*January
*February
*March
*April
*May
*June
*July
*August
*September
*October
*November
*December
*Archive Index
*Ask about this page
*Print this page
*Give us feedback
*Sign up for the Wolfram Insider

MathGroup Archive 2000

[Date Index] [Thread Index] [Author Index]

Search the Archive

Re: how to rank a list of elements?

  • To: mathgroup at smc.vnet.net
  • Subject: [mg23189] Re: how to rank a list of elements?
  • From: "Hermann Meier" <hmeier at webshuttle.ch>
  • Date: Mon, 24 Apr 2000 01:12:00 -0400 (EDT)
  • Organization: EUnet AG, Switzerland. A KPNQwest Company.
  • References: <8djk08$7dc@smc.vnet.net> <8dnuge$hrl@smc.vnet.net>
  • Sender: owner-wri-mathgroup at wolfram.com

The task was to rank elements of a list:
data = {15,7,15,20,1}

One of the elegant solutions of Mr. Hayes was:

Replace[data, Flatten[Apply[Rule, Split[Transpose[{Sort[data],
Range[Length[data]]}],
#1[[1]] == #2[[1]] &], {2}]], {1}]

which gives:
{3, 2, 3, 5, 1}


Replace can be slow with long data lists. The following basic Fortran-like
structure may be preferable (for no other reason than for speeding up
things):

ranks[DataVector_ /; VectorQ[DataVector,NumberQ]] :=
Module[{n=Length[DataVector],o,r},
o = Last[Transpose[Sort[Transpose[{DataVector,Range[n]}]]]];
r = Table[0,{n}]; Do[r[[ o[[i]] ]] = i,{i,n}];r ] /; (Signature[DataVector]
!= 0)

This only works  if no ties (equal values) are present; this is tested for
with Signature. (UnorderedUnion is from a message in this group some month
ago.)

UnorderedUnion[li_List] :=
Block[{i,Sequence}, i[n_] := (i[n] = Sequence[]; n); i /@ li]

untieddata= UnorderedUnion[data] gives:
{15,7,20,1}

ranks[untieddata] gives :
{3,2,4,1}

In nonparametric statistics, mid-ranks are often used if ties are present.
"When ties occur, each of them is assigned the average of the ranks that
would have been assigned had no ties occurred" (Siegel/Castellan,
Nonparametric Statistics, International Edition 1988, p. 239). The following
program may be used:

midranks[DataVector_ /; VectorQ[DataVector, NumberQ]] :=
Module[{srt = Sort[DataVector]},
Map[(p = Flatten[Position[srt, #]];
Apply[Plus, p]/Length[p]) &,
DataVector]] /; (Signature[DataVector] == 0)

midranks[data]//N gives:
{3.5,2.,3.5,5.,1}


With kind regards
Hermann Meier


"Allan Hayes" <hay at haystack.demon.co.uk> wrote in message
news:8dnuge$hrl at smc.vnet.net...
> Wen-Feng:
>
> One possibility.
> snipped ...

> ---------------------
> Allan Hayes
> Mathematica Training and Consulting
> Leicester UK
> www.haystack.demon.co.uk
> hay at haystack.demon.co.uk
> Voice: +44 (0)116 271 4198
> Fax: +44 (0)870 164 0565
>
>
>



  • Prev by Date: Re: fastest way to do pair-sum / make pair-list
  • Next by Date: RE: output from a package
  • Previous by thread: Re: how to rank a list of elements?
  • Next by thread: Re: how to rank a list of elements?