Estaba examinando todas estas opciones y comencé a preguntarme acerca de sus características y actuaciones relativas, así que hice algunas pruebas. En caso de que alguien más tenga curiosidad por lo mismo, estoy compartiendo mis resultados aquí.
Como no quería preocuparme por todas las funciones publicadas aquí, decidí centrarme en una muestra basada en algunos criterios: la función debería funcionar tanto en vectores de caracteres, factores, lógicos y numéricos, debería tratar los NA y otros valores problemáticos de manera adecuada, y la salida debe ser "sensata", es decir, sin números como caracteres u otras tonterías.
También agregué una función propia, que se basa en la misma rle
idea que la de chrispy, excepto que está adaptada para un uso más general:
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
Terminé ejecutando cinco funciones, en dos conjuntos de datos de prueba, a través microbenchmark
. Los nombres de las funciones se refieren a sus respectivos autores:
La función de Chris se estableció en method="modes"
yna.rm=TRUE
de forma predeterminada para que sea más comparable, pero aparte de eso, las funciones se usaron tal como las presentaron sus autores.
Solo en cuestión de velocidad, la versión de Kens gana fácilmente, pero también es el único de estos que solo informará un modo, sin importar cuántos haya realmente. Como suele ser el caso, hay una compensación entre velocidad y versatilidad. En method="mode"
, la versión de Chris devolverá un valor si hay un modo, de lo contrario NA. Creo que es un buen toque. También creo que es interesante cómo algunas funciones se ven afectadas por un mayor número de valores únicos, mientras que otras no lo son tanto. No he estudiado el código en detalle para entender por qué, aparte de eliminar la lógica / numérica como la causa.