我有一个包含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
如果我想通过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
到目前为止,这么好......名字保持正确的分数但是我怎么能重新排序它让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
如果我有2或3个因素,我知道怎么做。但是,如果我有严重的因素,比如20,我应该写一个for
循环吗?
答案 0 :(得分:20)
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
答案 1 :(得分:9)
以下是其他答案/评论中提到的所有方法的摘要(为未来的搜索者提供服务)。我添加了一个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),]
答案 2 :(得分:3)
我认为必须有类似的功能才能应用于数据帧 并获取数据框作为返回
是的,有:
library(plyr)
ddply(score, c('y', 'sex'))
答案 3 :(得分:2)
听起来我觉得你试图按照男性和女性的分数进行排序,并返回已排序的男性和排序女性的组合数据框。
你是对的by(score, score$sex, function(x) x[order(x$y),])
返回一个排序数据框列表,一个用于男性,一个用于女性。您可以将do.call
与rbind
函数结合使用,将这些数据框合并为一个最终数据框:
do.call(rbind, by(score, score$sex, function(x) x[order(x$y),]))
# x y sex
# F.5 EMMA 7.526866 F
# F.9 VIOLET 8.182407 F
# F.3 SUSAN 9.677511 F
# M.4 LARRY 6.929395 M
# M.8 MATT 7.970015 M
# M.7 TIM 8.297137 M
# M.6 LEONARD 8.845588 M
# M.2 TOM 9.035948 M
# M.1 MARK 10.082314 M