Search code examples
rsortingvectorindexingmatching

Sort values of named vector A by vector B but keeping the order of names where possible


I have a named vector like that:

my_vec <- c("Max"= "England", "Manfred"= "Germany", "Ingolf"= "Germany", "Paul"= "England", "Peter"= "Germany", "Nina"= "Italy")

I need to sort this vector by countries as specified in another vector while keeping the order of the persons for a given country as before. So if the ordering of the countries is...

sort_scheme <- c("England", "Germany", "Italy")

... then my desired output is:

goal_vec <- c("Max"= "England", "Paul"= "England", "Manfred"= "Germany", "Ingolf"= "Germany", "Peter"= "Germany", "Nina"= "Italy")

As you can see the desired output has the same order of countries as in sort_scheme (England first, then Germany, then Italy) and, inside one country the original order of names is the same (for England Max comes first then Paul, and so on). The solution should be flexible for other characters (new names and countries) with base R. All I've come up with is incredibly cumbersome.

Edit I found this being a duplicate and voted to close.


Solution

  • We can use order:

    my_vec[order(match(my_vec, sort_scheme))]

          Max      Paul   Manfred    Ingolf     Peter      Nina 
    "England" "England" "Germany" "Germany" "Germany"   "Italy" 
    

    As per @MerijnvanTilborg - if "nested" ordering using the vector names is required (which is not the case in the OP) we can use: my_vec[order(match(my_vec, sort_scheme), names(my_vec))]

    See ?order:

    In the case of ties in the first vector, values in the second are used to break the ties.