dplyr为每个类别选择前10个值

klsxnrf1  于 2023-06-03  发布在  其他
关注(0)|答案(3)|浏览(107)

我正在尝试过滤包含n个类别的n行的数据框。我希望每个类别dimension值按另一列revenues排序,然后选择每个dimension的前10个值,并删除其余的值。
我尝试了下面的代码片段,但似乎没有达到我想要的效果:

data <-  tbl_df(data) %>%
  arrange(revenues) %>%
  group_by(dimension) %>%
  top_n(10)
htrmnn0y

htrmnn0y1#

data <-  tbl_df(data) %>%
  group_by(dimension) %>%
  arrange(revenues, .by_group = TRUE) %>%
  top_n(10)
mutmk8jj

mutmk8jj2#

我们可以用一个示例数据来测试它:

set.seed(100)
data = data.frame(revenues=rnbinom(100,mu=1000,size=1),
dimension=sample(letters[1:2],100,replace=TRUE))

首先,正如@DarrenTsai正确指出的那样,您需要指定要执行top_n()的列。其次,当你使用top_n时,它按降序排列,并接受排名1-10的条目:

data %>% top_n(10,revenues)
   revenues dimension
1      4191         b
2      1916         a
3      2397         b
4      1895         a
5      2013         a
6      2351         b
7      3889         b
8      2503         a
9      3909         a
10     2779         b

这意味着你不需要安排你的数据,我不知道你是否打算采取降序或升序。假设它是递减的:

data %>%  group_by(dimension) %>% top_n(10,revenues)

请注意,上面的代码将取前10个值,这意味着在平局事件中(假设您有2个排名第一),您将获得超过10个。例如,在此数据中:

# A tibble: 21 x 2
# Groups:   dimension [2]
   revenues dimension
      <dbl> <fct>    
 1     1663 a        
 2     1663 a        
 3     1753 a        
 4     1849 a        
 5     1856 a        
 6     1869 a        
 7     1895 a        
 8     1916 a        
 9     2013 a        
10     2503 a        
# … with 11 more rows

我们可以看看结果是否正确,这是我们所期望的:

unlist(tapply(data$revenues,data$dimension,function(i)-sort(-i)[1:10]))
  a1   a2   a3   a4   a5   a6   a7   a8   a9  a10   b1   b2   b3   b4   b5   b6 
3909 2503 2013 1916 1895 1869 1856 1849 1753 1663 4191 3889 2779 2397 2351 1479 
  b7   b8   b9  b10 
1414 1340 1327 1274

使用group_by + top_n()

data %>%  group_by(dimension) %>% top_n(10,revenues) %>% 
arrange(dimension,desc(revenues)) %>% pull(revenues)
 [1] 3909 2503 2013 1916 1895 1869 1856 1849 1753 1663 1663 4191 3889 2779 2397
[16] 2351 1479 1414 1340 1327 1274

你可以看到1663被取了两次,总共给出了21个值。
如果你需要20个(每个10个):

data %>% arrange(desc(revenues)) %>%
group_by(dimension) %>% do(head(.,10))
2uluyalo

2uluyalo3#

data <-  tbl_df(data) %>%
  group_by(dimension) %>%
  arrange(desc(revenues),.by_group=TRUE) %>%
  top_n(10,revenues)

相关问题