如何对数据DT按ID和id分组,并挑出每组中b值最大的前两个观测,并保持观测在原有数据框中出现的顺序?我暂时还办不到保持顺序这一点,代码如下:

library(data.table)
#  原始数据 DT
DT<-data.table(
           ID=c("b","b","b","a","a","c",'b'),
           id=c('A','A','B','A','C','C','A'),
           a=1:7,b=c(10,100,2,3,50,500,20),c=13:19)
DT
#>    ID id a   b  c
#> 1:  b  A 1  10 13
#> 2:  b  A 2 100 14
#> 3:  b  B 3   2 15
#> 4:  a  A 4   3 16
#> 5:  a  C 5  50 17
#> 6:  c  C 6 500 18
#> 7:  b  A 7  20 19
# 目前的排序方法,无法保持观测出现顺序和原始的一致
DT[order(-b),.SD[1:2],by=list(ID,id)][!is.na(b)]
#>    ID id a   b  c
#> 1:  c  C 6 500 18
#> 2:  b  A 2 100 14
#> 3:  b  A 7  20 19
#> 4:  a  C 5  50 17
#> 5:  a  A 4   3 16
#> 6:  b  B 3   2 15
```

<sup>Created on 2020-07-19 by the [reprex package](https://reprex.tidyverse.org) (v0.3.0)</sup>
`

有排序有筛选,很难保持出现顺序。所以我的第一个问题是保持行顺序真是必要的吗?

如果必要的话,可以新增一列辅助变量rank记录原始顺序,最后根据rank排序即可。

library(data.table)
DT<-data.table(
           ID=c("b","b","b","a","a","c",'b'),
           id=c('A','A','B','A','C','C','A'),
           a=1:7,b=c(10,100,2,3,50,500,20),c=13:19)
DT
#>    ID id a   b  c
#> 1:  b  A 1  10 13
#> 2:  b  A 2 100 14
#> 3:  b  B 3   2 15
#> 4:  a  A 4   3 16
#> 5:  a  C 5  50 17
#> 6:  c  C 6 500 18
#> 7:  b  A 7  20 19

DT$rank=1:nrow(DT)

DT[order(-b),.SD[1:2],by=list(ID,id)][!is.na(b)][order(rank)]
#>    ID id a   b  c rank
#> 1:  b  A 2 100 14    2
#> 2:  b  B 3   2 15    3
#> 3:  a  A 4   3 16    4
#> 4:  a  C 5  50 17    5
#> 5:  c  C 6 500 18    6
#> 6:  b  A 7  20 19    7

<sup>Created on 2020-07-19 by the reprex package (v0.3.0.9000)</sup>

    library(data.table)
    DT<-data.table(
      ID=c("b","b","b","a","a","c",'b'),
      id=c('A','A','B','A','C','C','A'),
      a=1:7,b=c(10,100,2,3,50,500,20),c=13:19)
    
    DT[sort(DT[order(-b),head(.I,2),by = .(ID,id)]$V1)]
    #>    ID id a   b  c
    #> 1:  b  A 2 100 14
    #> 2:  b  B 3   2 15
    #> 3:  a  A 4   3 16
    #> 4:  a  C 5  50 17
    #> 5:  c  C 6 500 18
    #> 6:  b  A 7  20 19

    稍微解释一下,

    DT[order(-b),head(.I,2),by = .(ID,id)]$V1
    #> [1] 6 2 7 5 4 3

    data.table中使用head可以自动去除NA

    以上代码的结果是符合条件的原row number,即第6,2,7,5,4,3行

    再加一个sort即让它恢复原始的顺序

    tctcab 十分感谢您的解答!实际问题中应该不需要,我想请教一下技术上怎么实现。

      1 个月 后

      9-5-2-7 这是一个好问题,实际问题中,有可能会遇见。在 ggplot 中,图是一层一层叠加的,数据顺序可能影响图的样子。尤其是设置了alpha 值的时候。我就遇到过。