如何在dplyr中将奇数降序排列,偶数升序排列

4

I have following dataframe in 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  

我希望将奇数按降序排列,偶数按升序排列,并按bay分组。

我的期望数据框如下:

  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   

我该如何在dplyr中实现这个功能?

1
你的期望输出中为什么没有重新排列 ID 的原因是什么?你也想重新编号 ID 吗? - Aurèle
@Aurele 抱歉,我忘记改变输出。 - Neil
4个回答

6
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

使用基本R的变体:with(df, df[order(-bay, -(row%%2), row*(-1)^(row%%2)), ])df[order(-df$bay, -(df$row%%2), df$row*(-1)^(df$row%%2)), ] - Aurèle

2

对于一个基础解决方案,可以通过行是奇数还是偶数来分割数据,并使用 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)

2

使用基本的R语言中的aveorder,还有另一种选择:

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

这种方法受到这个答案的启发,但是使用ave对数据框中使用seq_along(dat$row)构造的行位置进行分组和添加顺序。根据这个向量,order内部的元素dat$row[x]将被子集化以控制分组。

结果返回:

   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

0

data.table 的另一个选项

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接