dplyr选取每个类别前10个值

4

我正在尝试过滤一个包含n个类别的数据框架,每个类别有n行。 我希望每个类别的dimension值按另一列revenues排序,然后选择每个dimension的前10个值并摆脱其余部分。

我尝试了以下代码片段,但似乎没有达到我想要的效果:

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

你能分享一下错误的源代码吗?否则我们将无法帮助你。 - linog
我没有收到错误信息,只是没有得到期望的输出。 - sanna
1
这个回答是否解答了你的问题?按组获取前几个值 - DJJ
这似乎是一个重复问题。当发帖提问时,我建议您避免在标题前加上dplyr,除非您是dplyr的专家。这可能会使您完全不必写问题。 - DJJ
这个回答解决了您的问题吗?[按组选择前N个值] (https://dev59.com/h2Uq5IYBdhLWcg3wF8hQ) - camille
3个回答

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

你需要在 top_n() 中指定按哪一列排序,否则它将默认按数据中的最后一个变量排序。 - Darren Tsai
1
对于后来的用户,top_n已被slice_minslice_max取代以明确顺序。在dplyr 1.0.10中不会被弃用。 未来更安全的语法是slice_max(revenues, n=10)表示最大的十个收入,而对于最小的收入使用slice_min。Slice有许多替代方法。您还可以按照现有的数据库顺序进行切片slice_head,或者如果您想要一个倾向于较大的收入项目的随机样本,假设替换,slice_sample(n = 10, replace = TRUE, weight_by = revenues) - micstr

2
我们可以使用示例数据进行测试:
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))

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

2
欢迎来到stackoverflow,感谢您分享您的答案。为了使您的答案更完整,重要的是您添加一些解释,随意指出原始帖子的问题所在。 - DJJ
谢谢,我会记住以后添加必要的解释。 - Raghuveer Machiraju

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接