【问题标题】:dplyr - Group by and select TOP x %dplyr - 分组并选择 TOP x %
【发布时间】:2016-01-18 04:05:42
【问题描述】:

使用包 dplyr 和函数sample_frac 可以从每个组中抽取一个百分比。我需要的是先对每个组中的元素进行排序,然后从每个组中选择 top x%?

有一个函数top_n,但是这里只能确定行数,需要一个相对值。

例如以下数据按齿轮分组,每组内按wt排序:

library(dplyr)
mtcars %>%
  select(gear, wt) %>%
  group_by(gear) %>%
  arrange(gear, wt)

    gear    wt
1   3   2.465
2   3   3.215
3   3   3.435
4   3   3.440
5   3   3.460
6   3   3.520
7   3   3.570
8   3   3.730
9   3   3.780
10  3   3.840
11  3   3.845
12  3   4.070
13  3   5.250
14  3   5.345
15  3   5.424
16  4   1.615
17  4   1.835
18  4   1.935
19  4   2.200
20  4   2.320
21  4   2.620
22  4   2.780
23  4   2.875
24  4   3.150
25  4   3.190
26  4   3.440
27  4   3.440
28  5   1.513
29  5   2.140
30  5   2.770
31  5   3.170
32  5   3.570

现在我想在每个齿轮组中选择前 20%。

如果该解决方案可以与 dplyr 的group_by 功能集成,那就太好了。

【问题讨论】:

  • 你不能自己计算百分比吗?我不确定这是否可行,因为我们没有可重现的示例,但我认为它可能:my_data %>% group_by(my_var) %>% arrange(my_var) %>% filter(top_n()/n() == x%)
  • @brittenb 感谢您的帮助! top_n() 不能在没有参数的情况下使用。

标签: r dplyr


【解决方案1】:

我相信这可以找到您正在寻找的答案。

library(dplyr)

mtcars %>% select(gear, wt) %>% 
  group_by(gear) %>% 
  arrange(gear, wt) %>% 
  filter(row_number() / n() <= .2)

【讨论】:

  • 完美!我认为在dplyr 中应该有一个实现这一点的函数。
  • 请记住,这种方法不允许“至少 20%”的方法。我的意思是,如果一个组有 4 行或更少,那么它不会选择其中任何一个,因为最小比率将大于 20%。所以请记住,您可能会像这样丢失数据。
  • @brittenb filter(row_number() &lt;= max(1,.2*n())) 如果你总是想保留至少一行呢?
  • @Frank 我认为如果您关心至少保留一个组的记录,这是一个好主意。这显然取决于问题的背景,这超出了这个问题的范围,但我只是想提出来。
【解决方案2】:

这是另一种方式

mtcars %>% 
  select(gear, wt) %>% 
  arrange(gear, desc(wt)) %>% 
  group_by(gear) %>% 
  slice(seq(n()*.2))

   gear    wt
  (dbl) (dbl)
1     3 5.424
2     3 5.345
3     3 5.250
4     4 3.440
5     4 3.440
6     5 3.570

我认为“top”的意思是“wt 的价值最高”,因此使用了desc()。

【讨论】:

  • 我应该可以写top_n(n()*.2) 来代替slice,但是唉,熟悉的Error in n() : This function should not be called directly 抬头了。
【解决方案3】:

或者使用 dplyr 的另一个选项:

mtcars %>% select(gear, wt) %>% 
  group_by(gear) %>% 
  arrange(gear, desc(wt)) %>% 
  filter(wt > quantile(wt, .8))

Source: local data frame [7 x 2]
Groups: gear [3]

   gear    wt
  (dbl) (dbl)
1     3 5.424
2     3 5.345
3     3 5.250
4     4 3.440
5     4 3.440
6     4 3.190
7     5 3.570

【讨论】:

  • 真正有创意的解决方案!非常感谢! :-)
  • 我会加入大多数并接受你的回答:-)
【解决方案4】:

我知道这来晚了,但现在可能会对某人有所帮助。 dplyr 有一个新函数 top_frac

  library(dplyr)
mtcars %>%
  select(gear, wt) %>%
  group_by(gear) %>%
  arrange(gear, wt) %>%
  top_frac(n = 0.2,wt = wt)

这里 n 是要返回的行的分数,wt 是用于排序的变量。

输出如下。

gear wt 3 5.250 3 5.345 3 5.424
4 3.440 4 3.440 5 3.570

【讨论】:

    【解决方案5】:

    使用 top_n 和 dplyr 的轻微变化:

    mtcars %>% 
     group_by(gear) %>% 
     select(gear, wt) %>% 
     arrange(gear) %>% 
     top_n(seq(n()*.2))
    
      gear    wt
      <dbl> <dbl>
    1     3  5.42
    2     3  5.34
    3     3  5.25
    4     4  3.44
    5     4  3.44
    6     5  3.57
    

    【讨论】:

      猜你喜欢
      • 2022-09-25
      • 2011-03-17
      • 2011-06-12
      • 2016-12-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多