On 14/12/2023 11:37 a.m., Martin Morgan wrote:
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.

I'd agree, in cases where it's feasible to implement one. But there are cases where the pairwise comparison is obvious, while the numeric conversion isn't.

A simple one would be a list of string vectors of different lengths, where you want to sort lexicographically.

Duncan


Have fun with the remainder of the advent!

Another Martin

From: R-help <r-help-boun...@r-project.org> on behalf of Martin Møller Skarbiniks 
Pedersen <traxpla...@gmail.com>
Date: Thursday, December 14, 2023 at 6:42 AM
To: R mailing list <r-help@r-project.org>
Subject: Re: [R] Sorting based a custom sorting function
On Thu, 14 Dec 2023 at 12:02, Duncan Murdoch <murdoch.dun...@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@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]]

______________________________________________
R-help@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.

______________________________________________
R-help@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.

Reply via email to