【问题标题】:Sort data.table by grouping variable with condition通过按条件对变量进行分组对 data.table 进行排序
【发布时间】:2020-04-01 16:52:40
【问题描述】:

我有以下data.table(实际上我的data.table 更大(更多组和更多其他变量)):

Data <- data.table(Group = rep(c("a", "b"), each = 3),
                   Var = 1:6)

> print(Data)
   Group Var
1:     a   1
2:     a   2
3:     a   3
4:     b   4
5:     b   5
6:     b   6

现在我想根据变量Groupdata.table 进行排序,但前提是Group == "a"。 我的糟糕尝试如下:

> Data[Group == "a", .SD[.N:1]]
   Group Var
1:     a   3
2:     a   2
3:     a   1

我知道为什么这是错误的,但我想不出一个能得到我想要的输出的解决方案:

   Group Var
1:     a   3
2:     a   2
3:     a   1
4:     b   4
5:     b   5
6:     b   6

【问题讨论】:

    标签: r sorting data.table grouping


    【解决方案1】:

    您的尝试将适用于

    library(data.table)
    Data[Group == "a"] <- Data[Group == "a", .SD[.N:1]]
    Data
    #    Group Var
    #1:     a   3
    #2:     a   2
    #3:     a   1
    #4:     b   4
    #5:     b   5
    #6:     b   6
    

    但是,如果您想根据Var 对行进行降序排序,则上述只是反转行,您可以这样做

    Data[Group == "a"] <- Data[Group == "a", .SD[order(-Var)]]
    

    如果你有多个列,你可以这样做

    cols <- c("a", "b")
    Data[Group %in% cols] <- Data[Group %in% cols,.SD[order(-Var)],Group]
    

    data.table 的更好方法是按照 @markus 的建议通过引用进行更新

    Data[Group %in% cols, Var := .SD[order(-Var)]$Var]
    

    【讨论】:

    • 谢谢!如果我有很多组并且我想为某些组排序行,我不确定这是否可行。
    • @RonakShah 你的第二种方法也可以写成Data[Group == "a", Var := .SD[order(-Var)]$Var],通过引用修改Var
    • @markus 是的,我正在尝试,但无法做到。谢谢,我已经更新了答案。
    【解决方案2】:

    不使用.SD 表示法:

    > Data[Group == "a", Var := sort(Var, decreasing = TRUE)]
    > Data
    
       Group Var
    1:     a   3
    2:     a   2
    3:     a   1
    4:     b   4
    5:     b   5
    6:     b   6
    

    由于您有一个较大的 data.table 和更多组,您可能希望考虑使用 .I 表示法(参见 @nathaneastwoodarticle),因为它在某些情况下会带来更好的性能。在这里,.I 将标识感兴趣的行号。让我们更改示例,以便我们对两个组感兴趣:

    Data <- data.table(Group = rep(c("a", "b", "c"), each = 3), Var = 10:18)
    

    然后:

    > Data[Data[, .I[Group  %in% c("a", "c")]], Var := sort(Var, decreasing = TRUE), by = Group]
    
    > Data
       Group Var
    1:     a  12
    2:     a  11
    3:     a  10
    4:     b  13
    5:     b  14
    6:     b  15
    7:     c  18
    8:     c  17
    9:     c  16
    

    为了完整起见,基本思想包含在:

    Data[Group %in% c("a", "c"), Var:= sort(Var, decreasing = TRUE), by = Group]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-10
      • 2016-06-13
      • 1970-01-01
      • 2021-12-01
      相关资源
      最近更新 更多