How to order a dataframe by a column with hyphen in dplyr

Viewed 31

I have a dataframe like below. I want to always have the dataframe in this order, but when I try to reorder the dataframe by id using dplyr::arrange(), it changes in a way that I don't want to. Is there any solution for this?

library(dplyr)
set.seed(10)
df <- data.frame(id = paste(2022,1:20, sep = "-"), weight = round(rnorm(20, 5, 1))) 
df
        id weight
1   2022-1      5
2   2022-2      5
3   2022-3      4
4   2022-4      4
5   2022-5      5
6   2022-6      5
7   2022-7      4
8   2022-8      5
9   2022-9      3
10 2022-10      5
11 2022-11      6
12 2022-12      6
13 2022-13      5
14 2022-14      6
15 2022-15      6
16 2022-16      5
17 2022-17      4
18 2022-18      5
19 2022-19      6
20 2022-20      5
wrong_order_df <- df %>% arrange(weight) %>% arrange(id)
wrong_order_df
        id weight
1   2022-1      5
2  2022-10      5
3  2022-11      6
4  2022-12      6
5  2022-13      5
6  2022-14      6
7  2022-15      6
8  2022-16      5
9  2022-17      4
10 2022-18      5
11 2022-19      6
12  2022-2      5
13 2022-20      5
14  2022-3      4
15  2022-4      4
16  2022-5      5
17  2022-6      5
18  2022-7      4
19  2022-8      5
20  2022-9      3

The idea that I came up with is to add a new column just for working on this issue. But I believe there is a more ellegant way.

correct_order_df <- wrong_order_df %>% mutate(id_order = as.numeric(str_extract(id, '\\b\\w+$'))) %>% arrange(id_order)
correct_order_df
        id weight id_order
1   2022-1      5        1
2   2022-2      5        2
3   2022-3      4        3
4   2022-4      4        4
5   2022-5      5        5
6   2022-6      5        6
7   2022-7      4        7
8   2022-8      5        8
9   2022-9      3        9
10 2022-10      5       10
11 2022-11      6       11
12 2022-12      6       12
13 2022-13      5       13
14 2022-14      6       14
15 2022-15      6       15
16 2022-16      5       16
17 2022-17      4       17
18 2022-18      5       18
19 2022-19      6       19
20 2022-20      5       20
1 Answers

You can input the specifications within arrange. Not sure how much more elegant we need than one line. Let me know if this works:

arrange(df, as.numeric(str_extract(id, "(?<=-)\\d+")))
Related