【问题标题】:Sort data frame column by factor按因子对数据框列进行排序
【发布时间】:2014-01-23 02:08:32
【问题描述】:

假设我有一个包含 3 列(nameysex)的数据框,其中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 循环吗?

【问题讨论】:

  • 您是否只想按多个变量排序,例如:score[order(score$y,score$sex,score$x),]
  • @thelatemail,听起来更像order(score$sex, score$y, score$x),而不是你建议的。
  • @AnandaMahto - 可能 - 你可以像 with(score,score[order(sex, y, x),]) 那样把它砍掉
  • 我应该阅读您的评论@thelate(或者您应该发布答案)。如果您将此作为答案发布,我将删除我的。

标签: r sorting r-factor


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    这里是其他答案/cmets 中提到的所有方法的摘要(为将来的搜索者服务)。我添加了一种 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)
    

    Here is Another question that deals with the same

    【讨论】:

      【解决方案3】:

      我认为必须有一些类似的功能可以应用于数据帧 并获取数据帧作为返回

      是的,有:

      library(plyr)
      
      ddply(score, c('y', 'sex'))
      

      【讨论】:

      • 问题是,为什么要使用plyr进行简单的订单操作?
      • @thelatemail,如果您使用plyr::arrange,您可以。即arrange(score, sex,y).
      • 我刚刚从一个错误中学到了一个很好的安排。如果您调用arrange(score,sex,y),它会像您说的那样工作,但是如果您调用arrange(score,y,sex),它会为您提供一个数据框,其中包含每个因素的最小值。那太棒了! (对不起,我是 R 新手)
      • 是“plyr”还是“dplyr”?
      【解决方案4】:

      在我看来,您正在尝试按男性和女性中的分数进行排序,并返回已排序男性和已排序女性的组合数据框。

      你说得对,by(score, score$sex, function(x) x[order(x$y),]) 返回一个排序后的数据框列表,一个是男性,一个是女性。您可以使用do.callrbind 函数将这些数据帧组合成一个最终数据帧:

      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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-11-20
        • 1970-01-01
        • 2011-11-12
        • 2021-10-29
        相关资源
        最近更新 更多