Martin Møller Skarbiniks Pedersen
2023-Dec-14 11:38 UTC
[R] Sorting based a custom sorting function
On Thu, 14 Dec 2023 at 12:02, Duncan Murdoch <murdoch.duncan at gmail.com> wrote:>> class(df$value) <- "sizeclass" > > `>.sizeclass` <- function(left, right) custom_sort(unclass(left), > unclass(right)) == 1 > > `==.sizeclass` <- function(left, right) custom_sort(unclass(left), > unclass(right)) == 0 > > `[.sizeclass` <- function(x, i) structure(unclass(x)[i], class="sizeclass") > > df[order(df$value),] > > All the "unclass()" calls are needed to avoid infinite recursion. For a > more complex kind of object where you are extracting attributes to > compare, you probably wouldn't need so many of those.Great! Just what I need. I will create a class and overwrite > and ==. I didn't know that order() used these exact methods. My best solution was something like this: quicksort <- function(arr, compare_func) { if (length(arr) <= 1) { return(arr) } else { pivot <- arr[[1]] less <- arr[-1][compare_func(arr[-1], pivot) <= 0] greater <- arr[-1][compare_func(arr[-1], pivot) > 0] return(c(quicksort(less, compare_func), pivot, quicksort(greater, compare_func))) } } persons <- c("alfa", "bravo", "charlie", "delta", "echo", "foxtrot", "golf", "hotel", "india", "juliett", "kilo", "lima", "mike", "november", "oscar", "papa", "quebec", "romeo", "sierra", "tango", "uniform", "victor", "whiskey", "x-ray", "yankee", "zulu") quicksort(persons, function(left, right) { nchar(left) - nchar(right) }) Regards Martin
In the spirit of 'advent of code', maybe it is better to exploit the features of the particular language you've chosen? Then the use of factors seems very relevant. value_levels <- c("Small", "Medium", "Large") df <- data.frame( person = c("Alice", "Bob", "Bob", "Charlie"), value = factor( c("Medium", "Large", "Small", "Large"), levels = value_levels ) ) df[with(df, order(person, value)),] Likely this is more efficient than the hints of your existing solution, because it will act on vectors rather than iterating through individual elements of the 'person' and 'value' vectors. For a more general solution, I don't think I'd follow the low-level approach Duncan suggests (maybe see also ?Math for S3 generics), but rather define a class (e.g., that requires vectors person and value) and implement a corresponding `xtfrm()` method. Have fun with the remainder of the advent! Another Martin From: R-help <r-help-bounces at r-project.org> on behalf of Martin M?ller Skarbiniks Pedersen <traxplayer at gmail.com> Date: Thursday, December 14, 2023 at 6:42?AM To: R mailing list <r-help at r-project.org> Subject: Re: [R] Sorting based a custom sorting function On Thu, 14 Dec 2023 at 12:02, Duncan Murdoch <murdoch.duncan at gmail.com> wrote:>> class(df$value) <- "sizeclass" > > `>.sizeclass` <- function(left, right) custom_sort(unclass(left), > unclass(right)) == 1 > > `==.sizeclass` <- function(left, right) custom_sort(unclass(left), > unclass(right)) == 0 > > `[.sizeclass` <- function(x, i) structure(unclass(x)[i], class="sizeclass") > > df[order(df$value),] > > All the "unclass()" calls are needed to avoid infinite recursion. For a > more complex kind of object where you are extracting attributes to > compare, you probably wouldn't need so many of those.Great! Just what I need. I will create a class and overwrite > and ==. I didn't know that order() used these exact methods. My best solution was something like this: quicksort <- function(arr, compare_func) { if (length(arr) <= 1) { return(arr) } else { pivot <- arr[[1]] less <- arr[-1][compare_func(arr[-1], pivot) <= 0] greater <- arr[-1][compare_func(arr[-1], pivot) > 0] return(c(quicksort(less, compare_func), pivot, quicksort(greater, compare_func))) } } persons <- c("alfa", "bravo", "charlie", "delta", "echo", "foxtrot", "golf", "hotel", "india", "juliett", "kilo", "lima", "mike", "november", "oscar", "papa", "quebec", "romeo", "sierra", "tango", "uniform", "victor", "whiskey", "x-ray", "yankee", "zulu") quicksort(persons, function(left, right) { nchar(left) - nchar(right) }) Regards Martin ______________________________________________ R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see https://stat.ethz.ch/mailman/listinfo/r-help PLEASE do read the posting guide http://www.R-project.org/posting-guide.html and provide commented, minimal, self-contained, reproducible code. [[alternative HTML version deleted]]