简体   繁体   English

如何在dplyr中以递增的顺序排列降序甚至偶数的奇数

[英]how to arrange odd numbers in descending and even even numbers in ascending order in dplyr

I have following dataframe in r 我在r中有以下数据帧

   ID     bay    row     number     
   1      43      11       ABC
   2      43      6        DEF
   3      43      13       QWE
   4      43      15       XDF
   5      43      4        VGH
   6      43      2        TYU
   7      11      11       QAS
   8      11      13       QTO
   9      11      12       EWQ
   10     11      10       RFT  

I want to arrange odd numbers in descending and even even numbers in ascending order grouping by bay 我想安排在下降奇数和偶数两类偶数升序排列分组bay

My desired dataframe would be following 我想要的数据框将遵循

  ID     bay     row     number     
  1       43      15      XDF
  2       43      13      QWE
  3       43      11      ABC
  4       43      2       TYU
  5       43      4       VGH
  6       43      6       DEF
  7       11      13      QTO 
  8       11      11      QAS
  9       11      10      RFT 
 10       11      12      EWQ   

How can I do this in dplyr ? 我怎么能在dplyr中这样做?

library(dplyr)

df <- read.table(text =
"   ID     bay    row     number     
   1      43      11       ABC
   2      43      6        DEF
   3      43      13       QWE
   4      43      15       XDF
   5      43      4        VGH
   6      43      2        TYU
   7      11      11       QAS
   8      11      13       QTO
   9      11      12       EWQ
   10     11      10       RFT ",
  stringsAsFactors = FALSE, header = TRUE)

arrange(df, desc(bay), desc(row %% 2), row * (-1)^(row%%2))

#    ID bay row number
# 1   4  43  15    XDF
# 2   3  43  13    QWE
# 3   1  43  11    ABC
# 4   6  43   2    TYU
# 5   5  43   4    VGH
# 6   2  43   6    DEF
# 7   8  11  13    QTO
# 8   7  11  11    QAS
# 9  10  11  10    RFT
# 10  9  11  12    EWQ

For a base solution, split the data by whether row is odd or even, and use mapply to sort them separately. 对于base解决方案,按row是奇数还是偶数来拆分数据,并使用mapply对它们进行单独排序。

df <- 
  structure(list(ID = 1:10, 
                 bay = c(43L, 43L, 43L, 43L, 43L, 43L, 
                         11L, 11L, 11L, 11L), 
                 row = c(11L, 6L, 13L, 15L, 4L, 2L, 11L, 
                         13L, 12L, 10L), 
                 number = c("ABC", "DEF", "QWE",
                            "XDF", "VGH", "TYU", 
                            "QAS", "QTO", "EWQ", 
                            "RFT")), 
            .Names = c("ID", "bay", "row", "number"), 
            class = "data.frame", 
            row.names = c(NA, -10L))

df <- split(df, df$row %%2 == 0)

df <- 
  mapply(function(DF, decr) DF[order(DF$row, decreasing = decr), ],
         df,
         decr = c(TRUE, FALSE),
         SIMPLIFY = FALSE)

df <- do.call("rbind", df)

Another option in base R using ave and order is 使用aveorder基本R中的另一个选项是

dat[ave(seq_along(dat$row), dat$bay,
        FUN=function(x) x[order(dat$row[x] * (-1)^dat$row[x])]),]

This method is inspired by this answer , but uses ave for grouping and addition orders on the row positions of the data.frame constructed with seq_along(dat$row) . 此方法受此答案的启发,但在使用seq_along(dat$row)构造的data.frame的行位置上使用ave进行分组和添加顺序。 The elements inside of order , dat$row[x] are subset according to this vector in order to control the grouping. order内的元素dat $ row [x]是根据该向量的子集,以便控制分组。

This returns 这回来了

   ID bay row number
4   4  43  15    XDF
3   3  43  13    QWE
1   1  43  11    ABC
6   6  43   2    TYU
5   5  43   4    VGH
2   2  43   6    DEF
8   8  11  13    QTO
7   7  11  11    QAS
10 10  11  10    RFT
9   9  11  12    EWQ

Another option with data.table data.table另一个选择

library(data.table)
setDT(dat)[order(row *(-1)^row), .SD, .(bay)]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM