【问题标题】:Multiple group_by and top_n with dplyr使用 dplyr 的多个 group_by 和 top_n
【发布时间】:2019-06-08 01:47:33
【问题描述】:

我有一个数据框,我正在尝试过滤和删除一些数据。 df 看起来像这样:

Event    Name    Team    Rank
1        Mike    B       1
1        Joe     A       2
1        Tom     C       3
1        Bill    B       4
2        Joe     A       1
2        Tom     C       2
...

我正在尝试过滤数据,因此我每人只有 3 个事件(按他们的最佳排名)和每个团队 18 人。

我能够使用以下方法每人获得 3 个事件:

df <- df %>% 
group_by(Name) %>%
top_n(-3,Rank)

但是每个团队的 18 人让我很受挫。我需要group_by 团队和姓名吗?如果是这样,怎么做?我尝试过的一切都没有奏效。

另外,我宁愿不打领带,但现在那是次要的。

编辑:这是一个很大的df,但结构如下:

structure(list(event = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 
3L, 3L, 3L, 3L, 3L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 6L, 
6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L, 6L), name = structure(c(22L, 
16L, 28L, 27L, 17L, 21L, 3L, 2L, 8L, 13L, 15L, 28L, 5L, 16L, 
17L, 2L, 22L, 3L, 10L, 21L, 5L, 15L, 24L, 29L, 1L, 2L, 18L, 25L, 
7L, 21L, 29L, 19L, 25L, 18L, 9L, 23L, 14L, 4L, 29L, 6L, 29L, 
19L, 9L, 26L, 25L, 14L, 4L, 11L, 20L, 12L), .Label = c("Andreas", 
"Andrej", "Blaise", "Brendan", "Coleman", "Colton", "Cooper", 
"Corben", "Eric", "Giovanni", "Graham", "Hayden", "Ian", "Jack", 
"Jacob", "Justin", "Kanoa", "Lane", "Marcelo", "Matthew", "Miles", 
"Nyls", "Robby", "Rodrigo", "Sadler", "T.C.", "Thomas", "Will", 
"Zach"), class = "factor"), team = structure(c(1L, 1L, 2L, 3L, 
2L, 4L, 5L, 6L, 7L, 3L, 1L, 2L, 1L, 1L, 2L, 6L, 1L, 5L, 1L, 4L, 
1L, 1L, 7L, 9L, 1L, 6L, 3L, 9L, 8L, 4L, 9L, 6L, 9L, 3L, 1L, 8L, 
1L, 8L, 6L, 7L, 9L, 6L, 1L, 6L, 9L, 1L, 8L, 6L, 8L, 6L), .Label = c("A", 
"B", "C", "D", "E", "F", "G", "H", "J"), class = "factor"), rank = c(1L, 
2L, 3L, 4L, 5L, 6L, 7L, 8L, 8L, 10L, 1L, 2L, 3L, 4L, 5L, 6L, 
7L, 8L, 9L, 10L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L, 1L, 
2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L, 1L, 2L, 3L, 4L, 5L, 6L, 
7L, 8L, 9L, 10L)), class = "data.frame", row.names = c(NA, -50L
))

【问题讨论】:

  • 您可以先创建一个完整的df 来使用吗?
  • 使用示例 df 进行了更新,但实际的行数约为 1400 行。
  • 您的示例数据框的预期输出是什么?
  • 输出应该和示例数据框一样。然而,每支队伍只允许 18 人参加,每人只允许参加 3 场比赛。所以我需要从每个团队中移除额外的人员,并为剩余人员移除额外的活动。我正在根据他们的最高级别删除人员。所以说完,每个团队应该有 18 人参加 3 项活动。
  • 您需要df %&gt;% group_by(team) %&gt;% top_n(-18, rank) %&gt;% ungroup() %&gt;% group_by(Name) %&gt;% top_n(-3,Rank) 吗?

标签: r dplyr


【解决方案1】:

这样的东西应该可以工作

df %>% 
group_by(name, team) %>%
filter(row_number() <= 18)

@NelsonGon 评论建议同时对两者进行分组,这似乎以更简洁的方式给出了确切的结果。

【讨论】:

  • 我离开了我的电脑。尝试同时按两者进行分组。
  • 我在上面添加了一个应该可以工作的 df。使用您的代码,每个团队我只能得到 18 行。我需要 18 个名字(他们的所有 3 个事件)
  • @BillK 这是一个很难诊断的问题,您的样本 df 只有少数人有 3 个事件。
【解决方案2】:

这个?

 library(tidyverse)
    df %>% 
      arrange(team,desc(rank)) %>% 
      group_by(event,team) %>% 
      top_n(3,rank)

电流输出:

   event name     team   rank
   <int> <fct>    <fct> <int>
 1     2 Giovanni A         9
 2     2 Nyls     A         7
 3     4 Jack     A         7
 4     6 Jack     A         6
 5     3 Andreas  A         5
 6     4 Eric     A         5
 7     2 Justin   A         4
 8     6 Eric     A         3
 9     1 Justin   A         2
10     3 Jacob    A         2

测试:

df %>% 
  arrange(team,desc(rank)) %>% 
  group_by(name,team) %>% 
  top_n(3,rank) %>% 
  filter(name=="Justin")
  event name   team   rank
  <int> <fct>  <fct> <int>
1     2 Justin A         4
2     1 Justin A         2

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-12-26
    • 1970-01-01
    • 1970-01-01
    • 2014-03-06
    • 2017-08-16
    • 2020-03-19
    • 2018-07-10
    相关资源
    最近更新 更多