set.seed(42)
df <- data.frame(letters=c(rep('data', 5), rep('oh', 5), rep('yeah', 5), rep('silly', 5)),
numbers=runif(n = 20, min = 1, max = 10))
我知道我可以按字母排序然后按字母排序然后按数字排序,像这样:
df[with(df, order(letters, numbers)), ]
很接近,但我想强制字母col首先按这个顺序排序c('silly', 'data', 'oh', 'yeah')
如何做到这一点?
我们可以使用match
df[with(df, order(match(letters, c('silly', 'data', 'oh', 'yeah')), numbers)),]
与产出
letters numbers
18 silly 2.057386
19 silly 5.274974
20 silly 6.042995
16 silly 9.460131
17 silly 9.804038
3 data 3.575256
5 data 6.775710
4 data 8.474029
1 data 9.233254
2 data 9.433679
8 oh 2.211999
6 oh 5.671864
9 oh 6.912931
10 oh 7.345583
7 oh 7.629295
14 yeah 3.298859
11 yeah 5.119676
15 yeah 5.160635
12 yeah 7.472010
13 yeah 9.412050
或者另一个选项是factor
,levels
按顺序指定
df[with(df, order(factor(letters, levels = c('silly', 'data', 'oh', 'yeah')), numbers)),]
下面是一个使用akrun提供的match
的dplyr
解决方案:
library(dplyr)
df %>%
arrange(match(letters, c('silly', 'data', 'oh', 'yeah')), numbers)
letters numbers
1 silly 2.057386
2 silly 5.274974
3 silly 6.042995
4 silly 9.460131
5 silly 9.804038
6 data 3.575256
7 data 6.775710
8 data 8.474029
9 data 9.233254
10 data 9.433679
11 oh 2.211999
12 oh 5.671864
13 oh 6.912931
14 oh 7.345583
15 oh 7.629295
16 yeah 3.298859
17 yeah 5.119676
18 yeah 5.160635
19 yeah 7.472010
20 yeah 9.412050