在 R 中按组变异

Dom*_* Jo 4 r window-functions dplyr mutate

我有一个包含以下列的数据:

    Date         CID      FID        rank  
    31/01/17     abc0001  rx180x01    0
    31/01/17     abc0001  rx180x02    0
    31/01/17     abc0001  rx180x03    2
    28/02/17     abc0001  rx180x32    1
    28/02/17     abc0001  rx180x31    0
Run Code Online (Sandbox Code Playgroud)

每个 CID 都有一些映射到它的唯一 FID,并且这些 FID 有一些排名。我需要创建 2 个新列 finalrank 和 finalFID。

最终排名是每个日期的每个 CID 的最大排名。即对于 CID abc0001,在日期 31/01/17 中,finalrank 将为 2。此逻辑将应用于所有唯一的 CID 日期组合。

FinalFID 是日期中 CID 具有特定 finalrank 值的 FID。例如,在日期 31/01/17,对于 CID abc0001,具有最大秩的 FID 为 rx180x03

所以我的结果应该是这样的:

    Date         CID      FID        rank  finalrank finalFID
    31/01/17     abc0001  rx180x01    0    2         rx180x03
    31/01/17     abc0001  rx180x02    0    2         rx180x03
    31/01/17     abc0001  rx180x03    2    2         rx180x03
    28/02/17     abc0001  rx180x32    1    1         rx180x32
    28/02/17     abc0001  rx180x31    0    1         rx180x32
Run Code Online (Sandbox Code Playgroud)

我写了一个看起来很优雅很好的代码,但它不适用于非常大的数据。我正在处理的那个有大约 5,000,000。当我在 R 中运行它时,它显示为如此庞大的数据帧运行没有其他内容。

       data          = dplyr::group_by(data,CID,date)
       data          = arrange(data,CID,date)
       data          = dplyr::mutate(data, finalrank =max(rank))

       # Id FID of maximum rank
       data   = dplyr::mutate(data, match = FID[match(finalrank ,rank)])
Run Code Online (Sandbox Code Playgroud)

Ony*_*mbu 5

dat%>%
   group_by(Date,CID)%>%
   mutate(finalrank=max(rank),finalFID=FID[which.max(rank)])
# A tibble: 5 x 6
# Groups:   Date, CID [2]
  Date     CID     FID       rank finalrank finalFID
  <fct>    <fct>   <fct>    <int>     <dbl> <fct>   
1 31/01/17 abc0001 rx180x01     0         2 rx180x03
2 31/01/17 abc0001 rx180x02     0         2 rx180x03
3 31/01/17 abc0001 rx180x03     2         2 rx180x03
4 28/02/17 abc0001 rx180x32     1         1 rx180x32
5 28/02/17 abc0001 rx180x31     0         1 rx180x32
Run Code Online (Sandbox Code Playgroud)

使用 data.table

library(data.table)
setDT(dat)[,c("finalrank","finalFID"):=.(max(rank),FID[which.max(rank)]),by=.(Date,CID)]
dat 
       Date     CID      FID rank finalrank finalFID
1: 31/01/17 abc0001 rx180x01    0         2 rx180x03
2: 31/01/17 abc0001 rx180x02    0         2 rx180x03
3: 31/01/17 abc0001 rx180x03    2         2 rx180x03
4: 28/02/17 abc0001 rx180x32    1         1 rx180x32
5: 28/02/17 abc0001 rx180x31    0         1 rx180x32
Run Code Online (Sandbox Code Playgroud)