R 按因子对数据帧列排序
假设我有一个数据框,有3列(R 按因子对数据帧列排序,r,sorting,r-factor,R,Sorting,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) sc
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
到目前为止,一切都很好。。。这些名字保持着正确的分数,但我如何才能重新排序,使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
sep
我想一定有类似的功能可以应用在数据帧上
并获取数据帧作为返回
是的,有:
library(plyr)
ddply(score, c('y', 'sex'))
对我来说,这听起来像是你试图在男性和女性之间按分数排序,然后返回排序男性和排序女性的组合数据框
您是对的,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
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
以下是其他答案/评论中提到的所有方法的摘要(为未来的搜索者服务)。我添加了一个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 sorts the data.table
setkey(score_dt,sex,x)
print(score_dt)
#基本R
do.call(rbind,by(score,score$sex,function(x)x[order(x$y),]))
有(分数,分数[顺序(性别,y,x),])
分数[顺序(分数$sex,分数$x),]
#使用plyr
排列(分数、性别、y)
ddply(得分,c(‘性别’,‘y’))
#使用`data.table`
库(“数据表”)
你只是想通过多个变量排序,比如:score[order(score$y,score$sex,score$x),]
?@thelatemail,听起来更像是order(score$sex,score$y,score$x)
,而不是你建议的那样。@AnandaMahto-可能-你可以用(score,score[order(sex,y,x),])来切碎它
我应该在@thelate阅读你的评论(或者你应该发布答案)。如果您将此作为答案发布,我将删除我的。问题是,为什么要使用plyr
进行简单的订单操作?@thelatemail,如果您使用plyr::arrange
,您可以。i、 e.arrange(分数、性别、y)
。我刚刚从一个错误中学到了arrange的大量用法。如果你调用arrange(score,sex,y),它就像你说的那样工作,但是如果你调用arrange(score,y,sex),它会给你一个每个因子的最小值的数据帧。太棒了!(对不起,我是R的新手)是“plyr”还是“dplyr”?
# 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 sorts the data.table
setkey(score_dt,sex,x)
print(score_dt)