我可以將自定義比較函式傳遞給order那個,給定兩個專案,指示哪個排名更高?
在我的具體情況下,我有以下串列。
scores <- list(
'a' = c(1, 1, 2, 3, 4, 4),
'b' = c(1, 2, 2, 2, 3, 4),
'c' = c(1, 1, 2, 2, 3, 4),
'd' = c(1, 2, 3, 3, 3, 4)
)
如果我們把兩個向量a和b,第一個元素的索引i處a[i] > b[i]或a[i] < b[i]應該確定矢量是第一位的。在這個例子中,scores[['d']] > scores[['a']]因為scores[['d']][2] > scores[['a']][2](請注意,這無關緊要scores[['d']][5] < scores[['a']][5])。
比較其中兩個向量可能看起來像這樣。
compare <- function(a, b) {
# get first element index at which vectors differ
i <- which.max(a != b)
if(a[i] > b[i])
1
else if(a[i] < b[i])
-1
else
0
}
scores使用此比較函式的排序鍵應該是d, b, a, c.
從我發現的其他解決方案中,他們在訂購或引入S3 類并應用比較屬性之前弄亂了資料。對于前者,我不知道如何弄亂我的資料(也許把它變成字串?但是超過 9 的數字呢?),對于后者,我覺得在我的 R 包中引入一個新類只是為了比較向量而感到不舒服。而且似乎沒有一種比較器引數我想傳遞給order.
uj5u.com熱心網友回復:
這是一個嘗試。我已經在評論中解釋了每一步。
compare <- function(a, b) {
# subtract vector a from vector b
comparison <- a - b
# get the first non-zero result
restult <- comparison[comparison != 0][1]
# return 1 if result == 1 and 2 if result == -1 (0 if equal)
if(is.na(restult)) {return(0)} else if(restult == 1) {return(1)} else {return(2)}
}
compare_list <- function(list_) {
# get combinations of all possible comparison
comparisons <- combn(length(list_), 2)
# compare all possibilities
results <- apply(comparisons, 2, function(x) {
# get the "winner"
x[compare(list_[[x[1]]], list_[[x[2]]])]
})
# get frequency table (how often a vector "won" -> this is the result you want)
fr_tab <- table(results)
# vector that is last in comparison
last_vector <- which(!(1:length(list_) %in% as.numeric(names(fr_tab))))
# return the sorted results and add the last vectors name
c(as.numeric(names(sort(fr_tab, decreasing = T))), last_vector)
}
如果在示例上運行該函式,結果是
> compare_list(scores)
[1] 4 2 1 3
兩個向量相同的情況我沒有處理過,你也沒有解釋如何處理。
uj5u.com熱心網友回復:
執行此操作的本機 R 方法是引入 S3 類。
你可以用這個類做兩件事。您可以定義一種xtfrm將串列條目轉換為數字的方法。這可以被矢量化,并且可以想象會非常快。
但是您要求的是用戶定義的比較函式。這會很慢,因為 R 函式呼叫很慢,而且有點笨拙,因為沒有人這樣做。但是按照xtfrm幫助頁面中的說明,這里是如何做到的:
scores <- list(
'a' = c(1, 1, 2, 3, 4, 4),
'b' = c(1, 2, 2, 2, 3, 4),
'c' = c(1, 1, 2, 2, 3, 4),
'd' = c(1, 2, 3, 3, 3, 4)
)
# Add a class to the list
scores <- structure(scores, class = "lexico")
# Need to keep the class when subsetting
`[.lexico` <- function(x, i, ...) structure(unclass(x)[i], class = "lexico")
# Careful here: identical() might be too strict
`==.lexico` <- function(a, b) {identical(a, b)}
`>.lexico` <- function(a, b) {
a <- a[[1]]
b <- b[[1]]
i <- which(a != b)
length(i) > 0 && a[i[1]] > b[i[1]]
}
is.na.lexico <- function(a) FALSE
sort(scores)
#> $c
#> [1] 1 1 2 2 3 4
#>
#> $a
#> [1] 1 1 2 3 4 4
#>
#> $b
#> [1] 1 2 2 2 3 4
#>
#> $d
#> [1] 1 2 3 3 3 4
#>
#> attr(,"class")
#> [1] "lexico"
由reprex 包(v2.0.1)于 2021 年 11 月 27 日創建
這與您要求的順序相反,因為默認情況下sort()按遞增順序排序。如果你真的想要 d, b, a, c 使用sort(scores, decreasing = TRUE.
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/368466.html
上一篇:Java快速排序性能
