如何使用dplyr按id分组,在数据框中筛选出某一列的前10%?

8

I have the following data frame:

id   total_transfered_amount day
1       1000                 2
1       2000                 3
1       3000                 4
1       1000                 1
1       10000                4
2       5000                 3
2       6000                 4
2       40000                2
2       4000                 3
2       4000                 3
3       1000                 1
3       2000                 2
3       3000                 3
3       30000                3
3       3000                 3

需要使用dplyr包,针对每个id分别过滤'total_transfered_amount'列中高于90百分位数的行,例如,我需要过滤以下行:

2       40000                2
3       30000                3

@akrun 欣赏你的想法。 - chessosapiens
@DatamineR 感谢您的帮助。 - chessosapiens
@Mateusz1981 我怀疑 sample_frac 是基于百分位概念工作的,我不想对列进行抽样,我想保留90个百分位数并且摆脱前10个百分位数中的虚假行。 - chessosapiens
你可以使用 quantile 进行检查。 - akrun
如何在deployer语法中使用group_by和filter进行连接? - chessosapiens
2个回答

9

请看这个。我不明白你的输出中为什么有第一行。

 dane <- data.frame(id = c(1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3,3 ), total_trans = c(1000, 2000, 3000, 1000, 10000, 5000, 6000, 
                                                                                            40000, 4000, 4000, 1000, 2000, 3000, 30000, 3000), 
                       day = c(2, 3,4, 1, 4, 3, 4, 2, 3, 3, 1, 2, 3, 3, 3))

    library(dplyr)




dane %>% group_by(id) %>% filter(quantile(total_trans, 0.9)<total_trans)





      id total_trans   day   
  (dbl)       (dbl) (dbl) 
1     1       10000     4  
2     2       40000     2 
3     3       30000     3 

编辑,我猜测10000可能高于90百分位数。 - chessosapiens
我认为你的答案缺少的是它计算整个列的百分位数,但我们需要为每个ID组单独执行。 - chessosapiens
但是quantile不是一个聚合函数,对吗? - chessosapiens
好的,我错过了。你想要每个“id”的0.9分位数,还是想要所有观测值的分位数值,然后选择所有“id”中高于该值的观测值? - Mateusz1981
2
你要寻找的dplyr命令是 dane %>% group_by(id) %>% filter(quantile(total_trans, 0.9)<total_trans) - ArunK
显示剩余7条评论

1
我们可以使用 data.table
 library(data.table)
 setDT(df1)[,.SD[quantile(total_transfered_amount, 0.9) < 
                total_transfered_amount] , by = id]
 #    id total_transfered_amount day
 #1:  1                   10000   4
 #2:  2                   40000   2
 #3:  3                   30000   3

或者我们可以使用 基础 R
df1[with(df1, as.logical(ave(total_transfered_amount, id, 
              FUN=function(x) quantile(x, 0.9) < x))),]
#   id total_transfered_amount day
#5   1                   10000   4
#8   2                   40000   2
#14  3                   30000   3

是的,正确的。如果我们想将其保留为数据框并使用dplyr呢? - chessosapiens
@sanaz data.table 应该可以和 dplyr 配合使用。如果需要更改为 data.frame,请使用 setDF(res) - akrun
问题在于我可能希望将代码迁移到R Spark,但目前R Spark中还没有data.table概念。 - chessosapiens
在这种情况下,您仍然可以使用“基本R”,对吧?df1[with(df1, ave(total_transfered_amount, id, FUN=function(x) quantile(x, 0.9) < x)),] - akrun

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