Przeglądałem wszystkie te opcje i zacząłem się zastanawiać nad ich względnymi funkcjami i wydajnością, więc zrobiłem kilka testów. W przypadku, gdy ktoś jest ciekawy tego samego, dzielę się tutaj swoimi wynikami.
Nie chcąc zawracać sobie głowy wszystkimi opublikowanymi tutaj funkcjami, postanowiłem skupić się na próbce opartej na kilku kryteriach: funkcja powinna działać zarówno na wektorach znakowych, czynnikowych, logicznych i liczbowych, powinna odpowiednio radzić sobie z NA i innymi problematycznymi wartościami, a dane wyjściowe powinny być „rozsądne”, tj. nie mogą zawierać znaków numerycznych ani innych podobnych głupstw.
Dodałem także własną funkcję, która opiera się na tej samej rle
idei co chrispy, z wyjątkiem tego, że jest przystosowana do bardziej ogólnego zastosowania:
library(magrittr)
Aksel <- function(x, freq=FALSE) {
z <- 2
if (freq) z <- 1:2
run <- x %>% as.vector %>% sort %>% rle %>% unclass %>% data.frame
colnames(run) <- c("freq", "value")
run[which(run$freq==max(run$freq)), z] %>% as.vector
}
set.seed(2)
F <- sample(c("yes", "no", "maybe", NA), 10, replace=TRUE) %>% factor
Aksel(F)
# [1] maybe yes
C <- sample(c("Steve", "Jane", "Jonas", "Petra"), 20, replace=TRUE)
Aksel(C, freq=TRUE)
# freq value
# 7 Steve
Skończyło się na tym, że uruchomiłem pięć funkcji na dwóch zestawach danych testowych microbenchmark
. Nazwy funkcji odnoszą się do ich autorów:
Funkcja Chrisa została ustawiona na method="modes"
ina.rm=TRUE
domyślnie, aby uczynić ją bardziej porównywalną, ale poza tym funkcje były używane w sposób przedstawiony tutaj przez ich autorów.
Jeśli chodzi o samą szybkość, wersja Kensa wygrywa z łatwością, ale jest to również jedyny z nich, który zgłasza tylko jeden tryb, bez względu na to, ile tak naprawdę jest. Jak to często bywa, istnieje kompromis między szybkością a wszechstronnością. W method="mode"
wersji Chris zwróci wartość, jeśli jest jeden tryb, w przeciwnym razie NA. Myślę, że to miły akcent. Myślę też, że to ciekawe, jak na niektóre funkcje wpływa zwiększona liczba unikalnych wartości, podczas gdy inne nie są tak bardzo. Nie studiowałem szczegółowo kodu, aby dowiedzieć się, dlaczego tak jest, oprócz wyeliminowania logicznej / numerycznej przyczyny.