如何使用fct_lump按组获取前n个级别,并将其余级别置于“其他”级别?

问题描述

我正在尝试根据一个汇总变量在每个组中找到前3个因子水平,然后将每个组的其余因子水平分组为“其他”。通常,我会为此使用fct_lump_n,但是我不知道如何在每个组中使用它。 这是一个示例,我要基于x变量形成组,根据z的值对y变量进行排序,选择前3个y变量,然后将y的其余部分分组为“其他”:

<div class="parent">4:3 ratio</div>

我尝试这样做:

set.seed(50)
df <- tibble(x = factor(sample(letters[18:20],100,replace = T)),y = factor(sample(letters[1:10],z = sample(100,replace = T))

返回以下内容

df %>%
  group_by(x) %>%
  arrange(desc(z),.by_group = T) %>%
  slice_head(n = 3)

这基本上是我想要的,但是我在r,s和t的每一个中都缺少“其他”变量,该变量收集了尚未计算的z值。

我可以为此使用fct_lump_n吗?还是slice_head结合将排除的变量分组为“其他”?

解决方法

在R 4.0.0和tidyverse 1.3.0中进行了尝试:

set.seed(50)
df <- tibble(x = factor(sample(letters[18:20],100,replace = T)),y = factor(sample(letters[1:10],z = sample(100,replace = T))

df %>%
  group_by(x) %>%
  arrange(desc(z)) %>%
  mutate(a = row_number(-z)) %>%
  mutate(y = case_when(a > 3 ~ "Other",TRUE ~ as.character(y))) %>%
  mutate(a = case_when(a > 3 ~ "Other",TRUE ~ as.character(a))) %>%
  group_by(x,y,a) %>%
  summarize(z = sum(z)) %>%
  arrange(x,a) %>%
  select(-a)

输出:

# A tibble: 12 x 3
# Groups:   x,y [11]
   x     y         z
   <fct> <chr> <int>
 1 r     b        92
 2 r     j        89
 3 r     g        83
 4 r     Other   749
 5 s     i        93
 6 s     h        93
 7 s     i        84
 8 s     Other  1583
 9 t     a        99
10 t     b        98
11 t     i        95
12 t     Other  1508

注意:将变量ay一起使用是为了补偿y 被替换采样的情况(请参见输出的第5和7行)。如果我不使用a,则输出的第5和第7行将汇总它们的z。还请注意,我尝试解决所提出的问题,但是我将y保留为字符,因为我认为这些“其他”不是同一因素水平。