# Rank

## Rank(x, i)

Rank(x, i) returns an array of the rank values of «x» across index «i». The lowest value in «x» has a rank value of 1, the next-lowest has a rank of 2, and so on. «i» is optional if «x» is one-dimensional. If «i» is omitted when «x» has more than one dimension, the innermost dimension is ranked. Since you, as a modeler, have little control over which dimension is the inner dimension, you should always specify «i» unless you can guarantee that «x» will always be one-dimensional.

## Examples

In the example below, the rank of a list is evaluated. Thus, the second parameter «i» is unnecessary. A one-dimensional array is returned, indexed by `Years`. This array has a value of 1 where `Year` has the smallest value, a value of 2 where `Year` has the second smallest value, and so on.

`Rank(Years) →`
Years ▶
2005 2006 2007 2008 2009
1 2 3 4 5

In the example below, the Rank function works with a multidimensional table. Each car type is given a rank for each year, with the cheapest car in that year given 1 and the most expensive car in that year given 3.

`Rank(Car_prices, Car_type) →`
Years ▶
Car_Type ▼ 2005 2006 2007 2008 2009
VW 1 1 1 1 1
Honda 2 2 2 2 2
BMW 3 3 3 3 3

## Optional Parameters

### Type

If two (or n) values are equal, they receive the same rank and the next higher value receives a rank 2 (or n) higher. You can use an optional parameter, «Type», to control which rank is assigned to equal values. By default, the lowest rank is used, equivalent to `Rank(x, i, Type: -1)` Alternatively, `Rank(x, i, Type: 0)` uses the mid-rank and `Rank(x, i, Type:1)` uses the upper-rank. `Rank(x, i, Type: Null)` assigns a unique rank to every element (the numbers 1 thru n) in which tied elements may have different ranks.

#### Example

The example below shows how the Rank function handles duplicate values.

`Rank(NumRepairs, CarNum, Type: RankType) →`
CarNum ▶
Rank Type ▼ 1 2 3 4 5 6 7
-1 7 2 6 2 2 1 2
0 7 3.5 6 3.5 3.5 1 3.5
1 7 5 6 5 5 1 5
Null 7 2 6 3 4 1 6
For `Type = -1`, lowest rank for the duplicate value is returned.
For `Type = 0`, mid rank value of the duplicates is returned.
For `Type = 1`, highest rank for the duplicate value is returned.
For `Type = Null`, unique rank value is returned.

### Case Sensitivity

When ranking text values, Rank treats text values as being case-sensitive with capital letters preceding lower case letters. So, for example, `Zebra` gets a lower rank than `apply`. In Analytica 4.2 or later, you can supply the optional parameter `caseInsensitive: true`:

`Rank(x, i, caseInsensitive: true)`

Case sensitivity only impacts text values.

### Descending rank

You can easily reverse the rank of numeric arrays, where the largest numbers receive the lowest ranks, by simply using `Rank(-X, i)`.

For arrays containing text values, in Analytica 4.2 and later you can specify the optional `descending: true` parameter

`Rank(x, i, descending: true)`

which uses the reverse rank order for text as well as numbers.

### Multi-key ranking

When two values are tied for the same rank, a second array can be used to break the tie. This is referred to as a multi-key sort (or multi-key rank). The first array is the primary key, the next is the secondary key, and so on. Analytica 4.2's Rank function support multi-key ranking. To use, your keys must all share a common index, «i». You must then introduce a new index, «keyIndex», to dimension your keys (any number of keys may be used), and bundle your keys into a 2-D array indexed by «i» and «keyIndex». For example, the following ranks by `age`, then, in case of a tie, by `gender`:

`Index keyIndex := ['age', 'gender'];`
`Rank(Array(keyIndex, [age, gender]), i, keyIndex)`

#### Example

This example shows how multi-key rank can be calculated by passing the optional «keyIndex» parameter to the rank function. The rank of the cars by the number of maintenance events using index `maintType` as the «keyIndex» is returned.

`Rank(NumMaintEvents, CarNum, keyIndex: maintType: RankType) →`
CarNum ▶
MaintType ▼ 1 2 3 4 5 6 7
Repair 10 4 9 4 4 1 4
Scheduled 0 2 0 1 2 0 5
Tires 0 2 0 0 1 0 0

### Treatment of NaN and Null values

When a NaN value occurs in your data, Rank can either pass it through as a NaN or assign it a numeric rank. The optional «passNaNs» parameter controls this behavior. The special value NaN indicates an indeterminate real number, which in theory cannot be compared to other numbers, so the ordering of NaN by Rank doesn't actually make logical sense. By passing NaN values through without assigning an actual rank, you may catch errors in your model that lead to the introduction of the NaN value in the first place, since these errors continue to be propagated to your results. This is often a desirable property.

By default, Rank assigns an arbitrary ranking to NaN values -- placing them between -INF and any finite numeric value. To pass NaNs, include the optional parameter `passNaNs: true`

`Rank(x, i, passNaNs: true).`

Null values are sometimes used for missing data, and in these cases can also be passed using the `passNulls: true` parameter. When this is not specified, null values are assigned a rank (with Null coming after all numeric values).