I have a data frame in R (R Shiny) that I want to sort based on a column that contains a mix of pure numerical (1, 3, 4, ...) values as well as 'numerical-string' (2a, 2b1, 2b2, 2c, ...) values.
The data frame I have is:
Column A | Column B |
---|---|
1 | Value 1 |
3 | Value 3 |
2a | Value 2a |
4 | Value 4 |
2b1 | Value 2b1 |
2c | Value 2c |
2b2 | Value 2b2 |
I want this sorted like this:
Column A | Column B |
---|---|
1 | Value 1 |
2a | Value 2a |
2b1 | Value 2b1 |
2b2 | Value 2b2 |
2c | Value 2c |
3 | Value 3 |
4 | Value 4 |
CodePudding user response:
In case of starting with more than one digits in ColumnA
, e.g., 10dxxx
, 211yxxx
, it is safer to separate the digits apart from the non-digit substrings (you can try sub
like below), and then apply order
> with(df, df[order(as.integer(sub("\\D.*", "", ColumnA)), sub("^\\d ", "", ColumnA)), ])
ColumnA ColumnB
1 1 Value 1
3 2a Value 2a
5 2b1 Value 2b1
7 2b2 Value 2b2
6 2c Value 2c
2 3 Value 3
4 4 Value 4
Data
> dput(df)
structure(list(ColumnA = c("1", "3", "2a", "4", "2b1", "2c",
"2b2"), ColumnB = c("Value 1", "Value 3", "Value 2a", "Value 4",
"Value 2b1", "Value 2c", "Value 2b2")), class = "data.frame", row.names = c(NA,
-7L))
CodePudding user response:
An option with mixedorder
library(dplyr)
df %>%
arrange(order(gtools::mixedorder(ColumnA)))
ColumnA ColumnB
1 1 Value 1
2 2a Value 2a
3 2b1 Value 2b1
4 2b2 Value 2b2
5 2c Value 2c
6 3 Value 3
7 4 Value 4