0

Suppose I have a data.frame df

library(tidyverse)
df<-data.frame(x=paste0("S", 1:15), y=letters[1:15], stringsAsFactors=F)%>%
              arrange(x)
     x y
1   S1 a
2  S10 j
3  S11 k
4  S12 l
5  S13 m
6  S14 n
7  S15 o
8   S2 b
9   S3 c
10  S4 d
11  S5 e
12  S6 f
13  S7 g
14  S8 h
15  S9 i

How can I arrange the x as an output like:

     x y
1   S1 a
2   S2 b
3   S3 c
4   S4 d
5   S5 e
6   S6 f
7   S7 g
8   S8 h
9   S9 i
10 S10 j
11 S11 k
12 S12 l
13 S13 m
14 S14 n
15 S15 o
David Z
  • 6,641
  • 11
  • 50
  • 101
  • I saw the post but I think they are different questions. – David Z Jun 13 '19 at 14:05
  • `df[gtools::mixedorder(df$x),]` seems to work fine. Also, what happens If you have something like `S01`? The accepted `nchar` answer might fail in this case – Sotos Jun 13 '19 at 14:09

4 Answers4

1

You can you the mixedorder() function in the gtools package to do this pretty easily.

library(gtools)

df<-data.frame(x=paste0("S", 1:15 ), y=letters[1:15], stringsAsFactors=F)


# mix it up
set.seed(121)
df <- df[sample(row.names(df), nrow(df)),]

# reorder it
df[mixedorder(df$x),]

That goes from this:

     x y
6   S6 f
3   S3 c
2   S2 b
15 S15 o
5   S5 e
12 S12 l
9   S9 i
10 S10 j
11 S11 k
8   S8 h
7   S7 g
1   S1 a
14 S14 n
13 S13 m
4   S4 d

to this

     x y
1   S1 a
2   S2 b
3   S3 c
4   S4 d
5   S5 e
6   S6 f
7   S7 g
8   S8 h
9   S9 i
10 S10 j
11 S11 k
12 S12 l
13 S13 m
14 S14 n
15 S15 o

In tidyverse you can do this -

df %>% 
  slice(mixedorder(x))
Shree
  • 10,835
  • 1
  • 14
  • 36
mfidino
  • 3,030
  • 1
  • 9
  • 13
1

Here's one possible way within dplyr -

df %>% 
  arrange(nchar(x), x)

     x y
1   S1 a
2   S2 b
3   S3 c
4   S4 d
5   S5 e
6   S6 f
7   S7 g
8   S8 h
9   S9 i
10 S10 j
11 S11 k
12 S12 l
13 S13 m
14 S14 n
15 S15 o
Shree
  • 10,835
  • 1
  • 14
  • 36
0

Well you could also add a pure numerical sequence column to your data frame and sort by that. Then, just scope the columns you actually want to see:

df<-data.frame(ord=c(1:15), x=paste0("S", 1:15), y=letters[1:15], stringsAsFactors=FALSE)
df[order(ord), c("x", "y")]
Tim Biegeleisen
  • 502,043
  • 27
  • 286
  • 360
0

Why not this?

df[order(nchar(df$x),df$x),]

Rahul Agarwal
  • 4,034
  • 7
  • 27
  • 51
TPArrow
  • 1,518
  • 18
  • 25