【问题标题】:Select a number of top groups from data frame从数据框中选择一些顶级组
【发布时间】:2020-04-12 12:35:07
【问题描述】:

有没有一种有效的方法可以从 R 中的数据框中获取一些顶级组? 例如:

exampleDf <- data.frame(
  subchar = c("facebook", "twitter", "snapchat", "male", "female", "18", "20"),
  superchar = c("social media", "social media", "social media", "gender", "gender", "age", "age"),
  cweight = c(.2, .4, .4, .7, .3, .8, .6),
  groupWeight = c(10, 10, 10, 20, 20, 70, 70)
)

因此,使用 dplyr 我可以将它们分组并按组权重排序:

sortedDf <- exampleDf %>%
  group_by(superchar) %>%
  arrange(desc(groupWeight))

但是在这种情况下,是否可以选择“顶级”组,例如年龄和性别?有点像 slice() dplyr 函数,但针对整个组而不是组内的行。

【问题讨论】:

  • “顶级群体”到底是什么意思?
  • 这似乎是一个奇怪的例子,因为groupWeight 在组中是唯一的,但它不是组 id,所以组并不重要。在这种情况下,我会做exampleDf %&gt;% filter(groupWeight %in% sort(unique(groupWeight), decreasing = TRUE)[1:2])。更有趣的情况是如果groupWeight 在组内变化,但您需要指定要使用groupWeight 的汇总函数(平均值、中值、最大值等)。而且可能最好的方法是exampleDf %&gt;% group_by %&gt;% summarize %&gt;% top_n %&gt;% left_join(exampleDf) 回到原始数据。
  • @heds1 抱歉应该澄清一下,在这种情况下,它将是 groupWeight 最高的组。所以这里的排名是年龄第一,然后是性别,社交媒体最低。

标签: r dataframe dplyr


【解决方案1】:

dplyr 有一个group_indices 函数,可以用来分配一个连续的组号。然后filter 用那个新号码。在下面的示例中,我将过滤/保留前 2 个组。

library(dplyr)

Top <- 2

sortedDf <- exampleDf %>%
  group_by(superchar) %>%
  arrange(desc(groupWeight)) %>%
  mutate(new_id = group_indices()) %>%
  filter(new_id <= Top) %>%
  select(-new_id)

sortedDf
## A tibble: 4 x 4
## Groups:   superchar [2]
#  subchar superchar cweight groupWeight
#  <fct>   <fct>       <dbl>       <dbl>
#1 18      age           0.8          70
#2 20      age           0.6          70
#3 male    gender        0.7          20
#4 female  gender        0.3          20

【讨论】:

    【解决方案2】:

    这里有另外两种使用 dplyr 的方法:

    我们为每个 superchar 计算 groupWeightsum 选择前 2 条记录,并使用原始数据框执行 left_join 以选择所有行。

    n <- 2
    library(dplyr)
    
    exampleDf %>%
      group_by(superchar) %>%
      summarise(sum_gr = sum(groupWeight)) %>%
      top_n(n, sum_gr) %>%
      left_join(exampleDf)
    
    # A tibble: 4 x 5
    #  superchar sum_gr subchar cweight groupWeight
    #  <fct>      <dbl> <fct>     <dbl>       <dbl>
    #1 age          140 18          0.8          70
    #2 age          140 20          0.6          70
    #3 gender        40 male        0.7          20
    #4 gender        40 female      0.3          20
    

    另一种方法是 sum groupWeight by superchar 并使用 dense_rank 选择顶级组。

    exampleDf %>%
      group_by(superchar) %>%
      mutate(sum_gr = sum(groupWeight)) %>%
      ungroup() %>%
      filter(dense_rank(-sum_gr) <= n)
    

    第一种方法可以用基数 R 写成:

    temp <- aggregate(groupWeight~superchar, exampleDf, sum)
    temp <- temp[order(temp$groupWeight, decreasing = TRUE), ][1:n, ]
    merge(temp, exampleDf, all.x = TRUE, by = 'superchar')
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-10-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-28
      • 2021-02-23
      • 2013-04-19
      相关资源
      最近更新 更多