R - 如何在保持分组的同时重新排列数据框中的行?

bra*_*ube 6 group-by r dplyr

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

# 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
Run Code Online (Sandbox Code Playgroud)

我怎样才能重新排列这些分组,使它们按氮值递减的顺序排列?我希望将数据框重新组织为类似于以下内容:

     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
Run Code Online (Sandbox Code Playgroud)

akr*_*run 5

我们可以按降序排列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
Run Code Online (Sandbox Code Playgroud)

-输出

# 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
Run Code Online (Sandbox Code Playgroud)

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

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

或使用 base R

data[order(with(data, factor(specie, levels = 
     unique(specie)[order(-value[condition == "Nitrogen"])]))),]
Run Code Online (Sandbox Code Playgroud)

数据

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"))
Run Code Online (Sandbox Code Playgroud)


Tho*_*ing 0

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

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

这使

              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
Run Code Online (Sandbox Code Playgroud)