【问题标题】:R - How to rearrange rows in a data frame while maintaining their grouping?R - 如何在保持分组的同时重新排列数据框中的行?
【发布时间】:2021-03-16 01:12:51
【问题描述】:

我有以下数据框。这些行目前按物种组排序,即高粱组,然后是 poacee 组。

# create a dataset
specie <- c(rep("sorgho" , 3) , rep("poacee" , 3) , rep("banana" , 3) , rep("triticum" , 3) )
condition <- rep(c("normal" , "stress" , "Nitrogen") , 4)
value <- abs(rnorm(12 , 0 , 15))
data <- data.frame(specie,condition,value)
print(data)

     specie condition     value
1    sorgho    normal 12.623696
2    sorgho    stress 11.394047
3    sorgho  Nitrogen  0.498003
4    poacee    normal 14.589322
5    poacee    stress 10.744153
6    poacee  Nitrogen  7.299742
7    banana    normal  9.845850
8    banana    stress  9.416088
9    banana  Nitrogen  4.178521
10 triticum    normal 13.230663
11 triticum    stress 30.658355
12 triticum  Nitrogen  9.402721

如何重新排列这些分组,使它们按氮值递减的顺序排列?我希望重新组织数据框,使其类似于:

     specie condition     value
10 triticum    normal 13.230663
11 triticum    stress 30.658355
12 triticum  Nitrogen  9.402721
4    poacee    normal 14.589322
5    poacee    stress 10.744153
6    poacee  Nitrogen  7.299742
7    banana    normal  9.845850
8    banana    stress  9.416088
9    banana  Nitrogen  4.178521
1    sorgho    normal 12.623696
2    sorgho    stress 11.394047
3    sorgho  Nitrogen  0.498003

【问题讨论】:

    标签: r dplyr group-by


    【解决方案1】:

    我们可以filter 'Nitrogen' 行,arrange 'value' 按降序提取'specie' 并将其用作levels 来`排列'specie' 列

    library(dplyr)
    lvls <- data %>% 
          filter(condition == 'Nitrogen') %>% 
          arrange(desc(value)) %>% 
          pull(specie) 
    data %>% 
            arrange(factor(specie, levels = lvls))%>%
            as_tibble
    

    -输出

    # A tibble: 12 x 3
    #   specie   condition  value
    #   <chr>    <chr>      <dbl>
    # 1 triticum normal    13.2  
    # 2 triticum stress    30.7  
    # 3 triticum Nitrogen   9.40 
    # 4 poacee   normal    14.6  
    # 5 poacee   stress    10.7  
    # 6 poacee   Nitrogen   7.30 
    # 7 banana   normal     9.85 
    # 8 banana   stress     9.42 
    # 9 banana   Nitrogen   4.18 
    #10 sorgho   normal    12.6  
    #11 sorgho   stress    11.4  
    #12 sorgho   Nitrogen   0.498
    

    或者在单个管道中执行此操作

    data %>%
        arrange(factor(specie, levels = 
              unique(specie)[order(-value[condition == 'Nitrogen'])]))
    

    或使用base R

    data[order(with(data, factor(specie, levels = 
         unique(specie)[order(-value[condition == "Nitrogen"])]))),]
    

    数据

    data <- structure(list(specie = c("sorgho", "sorgho", "sorgho", "poacee", 
    "poacee", "poacee", "banana", "banana", "banana", "triticum", 
    "triticum", "triticum"), condition = c("normal", "stress", "Nitrogen", 
    "normal", "stress", "Nitrogen", "normal", "stress", "Nitrogen", 
    "normal", "stress", "Nitrogen"), value = c(12.623696, 11.394047, 
    0.498003, 14.589322, 10.744153, 7.299742, 9.84585, 9.416088, 
    4.178521, 13.230663, 30.658355, 9.402721)), class = "data.frame",
    row.names = c("1", 
    "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"))
    

    【讨论】:

      【解决方案2】:

      另一个基本 R 选项(不如 @akrun 的基本 R 解决方案优雅)

      with(
        data,
        do.call(
          rbind,
          split(data, factor(specie, levels = unique(specie)))[order(-value[condition == "Nitrogen"])]
        )
      )
      

      给了

                    specie condition     value
      triticum.10 triticum    normal 13.230663
      triticum.11 triticum    stress 30.658355
      triticum.12 triticum  Nitrogen  9.402721
      poacee.4      poacee    normal 14.589322
      poacee.5      poacee    stress 10.744153
      poacee.6      poacee  Nitrogen  7.299742
      banana.7      banana    normal  9.845850
      banana.8      banana    stress  9.416088
      banana.9      banana  Nitrogen  4.178521
      sorgho.1      sorgho    normal 12.623696
      sorgho.2      sorgho    stress 11.394047
      sorgho.3      sorgho  Nitrogen  0.498003
      

      【讨论】:

        【解决方案3】:

        这可以通过data.table 轻松完成。我们首先以所需的顺序获得specie 的单列data.table。然后以 data.table 方式合并将给出所需的输出。对于dt.orderedspecie 的每个值,将返回来自data 的匹配行。因此,最终输出中specie列的顺序由dt.ordered中的顺序决定。

        library(data.table)
        setDT(data)
        
        dt.ordered <- data[condition == 'Nitrogen', .(specie = specie[order(-value)])]
        # > dt.ordered
        #      specie
        # 1: triticum
        # 2:   poacee
        # 3:   banana
        # 4:   sorgho
        
        data[dt.ordered, on = .(specie)]
        
        #      specie condition     value
        #  1: triticum    normal 13.230663
        #  2: triticum    stress 30.658355
        #  3: triticum  Nitrogen  9.402721
        #  4:   poacee    normal 14.589322
        #  5:   poacee    stress 10.744153
        #  6:   poacee  Nitrogen  7.299742
        #  7:   banana    normal  9.845850
        #  8:   banana    stress  9.416088
        #  9:   banana  Nitrogen  4.178521
        # 10:   sorgho    normal 12.623696
        # 11:   sorgho    stress 11.394047
        # 12:   sorgho  Nitrogen  0.498003
        

        万岁data.table :)

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-11-03
          • 2018-07-18
          • 1970-01-01
          • 2013-07-03
          • 2012-10-01
          • 1970-01-01
          相关资源
          最近更新 更多