按因子对数据框列进行排序

Mat*_*ina 16 sorting r r-factor

我有一个3列(name,, )的数据框y,sex其中name是字符,y是一个数值,sex是一个因子.

sex<-c("M","M","F","M","F","M","M","M","F")
x<-c("MARK","TOM","SUSAN","LARRY","EMMA","LEONARD","TIM","MATT","VIOLET")
name<-as.character(x)
y<-rnorm(9,8,1)
score<-data.frame(x,y,sex)
score
     name      y     sex
1    MARK  6.767086   M
2     TOM  7.613928   M
3   SUSAN  7.447405   F
4   LARRY  8.040069   M
5    EMMA  8.306875   F
6 LEONARD  8.697268   M
7     TIM 10.385221   M
8    MATT  7.497702   M
9  VIOLET 10.177969   F
Run Code Online (Sandbox Code Playgroud)

如果我想订购,y我会使用:

score[order(score$y),]
        x         y sex
1    MARK  6.767086   M
3   SUSAN  7.447405   F
8    MATT  7.497702   M
2     TOM  7.613928   M
4   LARRY  8.040069   M
5    EMMA  8.306875   F
6 LEONARD  8.697268   M
9  VIOLET 10.177969   F
7     TIM 10.385221   M
Run Code Online (Sandbox Code Playgroud)

到目前为止,这么好...名字保持正确的分数但是我怎么能重新排序它让M和F级别没有混合.我需要订购并同时保持因子水平分开.

最后我想进一步涉及角色,这个例子没有帮助,但是如果有绑定的y值,我将不得不在因子内再次订购(例如TIM和TOM得到8.4,我必须按字母顺序排列).

我正在考虑功能,但它创建了一个列表,并没有真正帮助.我认为必须有一些类似的函数应用于数据帧并获取数据帧作为返回.

要明确要点:

sep<-split(score,score$sex)
sep$M<-sep$M[order(sep$M[,2]),]
sep$M
x         y sex
1    MARK  6.767086   M
8    MATT  7.497702   M
2     TOM  7.613928   M
4   LARRY  8.040069   M
6 LEONARD  8.697268   M
7     TIM 10.385221   M

sep$F<-sep$F[order(sep$F[,2]),]
sep$F
x         y sex
3  SUSAN  7.447405   F
5   EMMA  8.306875   F
9 VIOLET 10.177969   F

merged<-rbind(sep$M,sep$F)
merged
x         y sex
1    MARK  6.767086   M
8    MATT  7.497702   M
2     TOM  7.613928   M
4   LARRY  8.040069   M
6 LEONARD  8.697268   M
7     TIM 10.385221   M
3   SUSAN  7.447405   F
5    EMMA  8.306875   F
9  VIOLET 10.177969   F
Run Code Online (Sandbox Code Playgroud)

如果我有2或3个因素,我知道怎么做.但是,如果我有严重的因素,比如20,我应该写一个for循环怎么办?

Mat*_*erg 23

order 采用多个参数,它只是你想要的:

with(score, score[order(sex, y, x),])
##         x        y sex
## 3   SUSAN 6.636370   F
## 5    EMMA 6.873445   F
## 9  VIOLET 8.539329   F
## 6 LEONARD 6.082038   M
## 2     TOM 7.812380   M
## 8    MATT 8.248374   M
## 4   LARRY 8.424665   M
## 7     TIM 8.754023   M
## 1    MARK 8.956372   M
Run Code Online (Sandbox Code Playgroud)


mar*_*bel 10

以下是其他答案/评论中提到的所有方法的摘要(为未来的搜索者提供服务).我添加了一个data.table排序方式.

# Base R
do.call(rbind, by(score, score$sex, function(x) x[order(x$y),]))
with(score, score[order(sex, y, x),])
score[order(score$sex,score$x),]

# Using plyr
arrange(score, sex,y)
ddply(score, c('sex', 'y'))

# Using `data.table`
library("data.table")
score_dt <- setDT(score)

# setting a key works just fine
setkey(score_dt,sex,x)
print(score_dt)

# Explicitly ordering using i
score_dt[i=order(sex,x),]
Run Code Online (Sandbox Code Playgroud)

这是另一个处理相同的问题