R語言rank函數詳細解析

1.rank函數是什麼數組

rank相關文檔[1]能夠譯爲"返回原數組(?)中各個元素排序(?)後的秩次(?)",表面上看確實能夠獲得次序,但對數組、排序、秩次交待不清。dom

2.rank函數使用情景函數

好比,在100米賽跑中,甲乙丙三人的成績爲6.8s, 8.1s, 7.2s,那麼用rank函數排序得到名次編碼

> rank(t <- c(6.8, 8.1, 7.2))
[1] 1 3 2

再如,甲乙丙三人考試得分爲74,92,85,用一樣方法取得名次會拔苗助長。固然,咱們能夠認爲執行spa

> rank(-(s <- c(74, 92, 85)))
[1] 3 1 2

能夠達到目的,但這並未改變rank函數的排序機制。設計

3.rank函數排序類型code

rank(x, na.last = TRUE,
     ties.method = c("average", "first", "random", "max", "min"))blog

> t <- c(4, NaN, 4, 7, 8, 2, NaN, 9, 9, 7, NaN, 5, 2, 2, 1)
#同時對相應元素作好標記
> names(t) <- letters[1 : length(t)]

經過以上方法進行排序,得出排序

Result
  a b c d e f g h i j k l m n o
original 4 NaN 4 7 8 2 NaN 9 9 7 NaN 5 2 2 1
average 5.5 13.0 5.5 8.5 10.0 3.0 14.0 11.5 11.5 8.5 15.0 7.0 3.0 3.0 1.0
first 5 13 6 8 10 2 14 11 12 9 15 7 3 4 1
random (1) 6 13 5 9 10 2 14 11 12 8 15 7 3 4 1
random (2) 5 13 6 8 10 2 14 11 12 9 15 7 4 3 1
max 6 13 6 9 10 4 14 12 12 9 15 7 4 4 1
min 5 13 5 8 10 2 14 11 11 8 15 7 2 2 1

咱們發現,標籤"b","g","k"的次序並未發生改變,可推斷ties.method做用在於處理非缺失值的順序文檔

不妨參考rank的實現代碼

function (x, na.last = TRUE, ties.method = c("average", "first", 
    "random", "max", "min")) 
{
    nas <- is.na(x) #獲得與x相同長度的boolean型數組,用來標記相應位是否爲缺失值
    nm <- names(x)  #獲取數組中元素所對應的標籤
  #names函數暗示了該方法的設計初衷是對一維數組即列向量進行排序,雖然x爲矩陣也會得出結果,但nm的做用已經失效,結果不具備意義
   ties.method
<- match.arg(ties.method) if (is.factor(x)) x <- as.integer(x) #若x爲因子,則對元素"歸類",並按"類的大小"進行整數元素編碼,具體請見[說明1] x <- x[!nas] #剔除x中的缺失值

  #average\min\max採用了相應的.Internal(rank(x, length(x), ties.method)),具體請見[說明2]
  #first採用了sort.list(sort.list(x)),具體請見[說明3]
  #random採用了sort.list(order(x, stats::runif(sum(!nas)))),具體請見[說明4] y
<- switch(ties.method, average = , min = , max = .Internal(rank(x, length(x), ties.method)), first = sort.list(sort.list(x)), random = sort.list(order(x, stats::runif(sum(!nas)))))

  #下面是補全缺失值的次序的方法
  #na.last = "keep",不處理缺失值,na.last = TRUE,後排序缺失值,na.last = FALSE,先排序缺失值。
if (!is.na(na.last) && any(nas)) { yy <- NA NAkeep <- (na.last == "keep") if (NAkeep || na.last) { yy[!nas] <- y if (!NAkeep) yy[nas] <- (length(y) + 1L):length(yy) } else { len <- sum(nas) yy[!nas] <- y + len yy[nas] <- seq_len(len) } y <- yy names(y) <- nm } else names(y) <- nm[!nas] y }

[說明1] 關於因子轉整數

> f <- c('Ba', 'BA', 'b', 'A', 'A', 'b', 'Ba', 'Bac', NaN, NaN)
> fac <- factor(colour)
> as.integer(fac)
 [1] 3 4 2 1 1 2 3 5 6 6

因而可知: (1) 因子會做爲字符串進行機械比較,排出次序。(2) 因子中任意兩個缺失值地位(大小)相同。

實際問題中,因子爲人爲設定,故採用有序因子(ordered factor),消除機械轉換的干擾。

> qulity <- c('good','soso','good','soso','bad','good','bad')
> names(qulity) <- c('day1','day2','day3','day4','day5','day6','day7')
> q <- factor(qulity, levels = c('bad','soso','good'), labels = c('bad', 'soso', 'good'), order = TRUE)
> rank(q)
day1 day2 day3 day4 day5 day6 day7 
 6.0  3.5  6.0  3.5  1.5  6.0  1.5 

[說明2] "average", "max", "min" 排序

> t
  a   b   c   d   e   f   g   h   i   j   k   l   m   n   o 
  4 NaN   4   7   8   2 NaN   9   9   7 NaN   5   2   2   1 
> rank(t, na.last = "keep", ties.method = "first")
 a  b  c  d  e  f  g  h  i  j  k  l  m  n  o 
 5 NA  6  8 10  2 NA 11 12  9 NA  7  3  4  1 
> rank(t, na.last = "keep", ties.method = "average")
   a    b    c    d    e    f    g    h    i    j    k    l    m    n    o 
 5.5   NA  5.5  8.5 10.0  3.0   NA 11.5 11.5  8.5   NA  7.0  3.0  3.0  1.0 

能夠將"average"排序理解爲先對數據進行"first"排序,即所有元素都有惟一且不一樣的次序。

如f, m, n 得分相同,但可按前後次序排成2, 3, 4, 可是f, m, n屬於同一羣體,故能夠取該羣體中的平均水平做爲次序,使得分相同的元素地位至關。

故不難理解"max"排序是羣體中的元素所有取羣中最好的水平,這也是廣泛採用的「並列排名」方法;

"min"排序是羣體中的元素所有取羣體中最差的水平,這樣增大了不一樣等級的順序差別。

 [說明3] first = sort.list(sort.list(x))

對序列先按大小排序,大小相同的元素,從頭到尾由小到大排序。

> x
a c d e f h i j l m n o 
4 4 7 8 2 9 9 7 5 2 2 1 
> sort.list(sort.list(x))
 [1]  5  6  8 10  2 11 12  9  7  3  4  1

[說明4] random = sort.list(order(x, stats::runif(sum(!nas))))

weight = stats::runif(sum(!nas)) 爲每一個已知元素生成0-1之間隨機數,做爲「權重」序列weight

sort.list(order(x, weigth)) 依據隨機的「權重」決定得分相同的元素的次序

不妨人爲參與權重設計

a c d e f h i j l m n o 
4 4 7 8 2 9 9 7 5 2 2 1 
> weight = c(0.45, 0.55, 0.1, 0.1, 0.1, 0.55, 0.45, 0.1, 0.1, 0.3, 0.1, 0.1);
> sort.list(order(x,weight))
 [1]  5  6  8 10  2 12 11  9  7  4  3  1

不難發現,a, c 得分均爲4,但w(a) = 0.45 < w(c) = 0.55, 遵守小號在前,a 排在c 前面。h, j 恰好相反w(h) = 0.55 > w(j) = 0.45, j 排在h 前面。

d, j 得分,「權重」均相同,故按以前從頭至尾遞增順序排列。

f, m, n 得分均爲2, w(f) = w(n) = 0.1 < w(m) = 0.3, 排序結果爲f < n < m, 因而可知,「權重」優先於「先後順序」,這樣作使得排序更加隨機化,若序列存在大量得分相同的元素,必定程度克服了「前小後大」規則的約束,使排序結果更隨機。

以上僅爲說明隨機排序的機制,實際應用中只能肯定小數在前大數在後,並不能解釋相同的數之間的順序。

4.rank函數小結

rank(x, na.last = TRUE,
     ties.method = c("average", "first", "random", "max", "min"))

(1) rank 函數是對一維度數組、向量x 進行排序。若x 爲數值,則按照小數在線大數在後的原則進行排序,若x 爲因子,則應參考[說明1]進行順序因子設計。

P.S. 實際狀況中,存在大量用二維表格描述的數據,好比行表示地點列表示時間的統計表,若進行排序,應先經過字符拼接的手段將表格轉化爲一維的向量,不然結果將失去意義。

(2) rank 將數據分爲肯定值與缺失值兩種。缺失值可按前後排在肯定值之間(na.last = FALSE), 也可排在以後(na.last = TRUE), 也可保留,不參與排序(na.last = "keep").

(3) "first" 是最基本的排序,小數在前大數在後,相同元素先者在先後者在後。

  "max" 是相同元素都取該組中最好的水平,即一般所講的並列排序。

  "min" 是相同元素都取該組中最差的水平,能夠增大序列的等級差別。

  "average" 是相同元素都取該組中的平均水平,該水平多是個小數。

  "random" 是相同元素隨機編排次序,避免了「先到先得」,「權重」優於「前後順序」的機制增大了隨機的程度。

[1]Returns the sample ranks of the values in a vector. Ties (i.e., equal values) and missing values can be handled in several ways.

相關文章
相關標籤/搜索