有联系时如何汇总数据集中的前3个最高值

时间:2019-05-11 17:06:19

标签: r dplyr top-n

我有一个数据帧(my_data),即使可能有联系,我也想仅计算3个最大值的总和。我对R很陌生,并且使用过dplyr

A tibble: 15 x 3
   city      month number
   <chr>     <chr>  <dbl>
 1 Lund      jan       12
 2 Lund      feb       12
 3 Lund      mar       18
 4 Lund      apr       28
 5 Lund      may       28
 6 Stockholm jan       15
 7 Stockholm feb       15
 8 Stockholm mar       30
 9 Stockholm apr       30
10 Stockholm may       10
11 Uppsala   jan       22
12 Uppsala   feb       30
13 Uppsala   mar       40
14 Uppsala   apr       60
15 Uppsala   may       30

这是我尝试过的代码:

# For each city, count the top 3 of variable number
my_data %>% group_by(city) %>% top_n(3, number) %>% summarise(top_nr = sum(number))

期望的(期望的)输出为:

# A tibble: 3 x 2
  city      top_nr
  <chr>      <dbl>
1 Lund          86
2 Stockholm     75
3 Uppsala      130

但实际的R输出为:

# A tibble: 3 x 2
  city      top_nr
  <chr>      <dbl>
1 Lund          86
2 Stockholm     90
3 Uppsala      160

似乎存在联系,所有捆绑值都包含在求和中。我只希望计算3个唯一的具有最高值的实例。

任何帮助将不胜感激! :)

4 个答案:

答案 0 :(得分:4)

我们可以执行distinct来删除重复的元素。 top_n的工作方式是:如果值重复,它将保留那么多重复行

my_data %>% 
   distinct(city, number, .keep_all = TRUE) %>%
   group_by(city) %>%
   top_n(3, number) %>%
   summarise(top_nr = sum(number))

更新

基于OP的新输出,在top_n输出(不是arrange d)之后,获得降序排列的“数字”并获得前3个的sum '数字'

my_data %>% 
   group_by(city) %>% 
   top_n(3, number) %>% 
   arrange(city,  desc(number)) %>% 
   summarise(number = sum(head(number, 3)))
# A tibble: 3 x 2
#  city      number
#  <chr>      <int>
#1 Lund          74
#2 Stockholm     75
#3 Uppsala      130

数据

my_data <- structure(list(city = c("Lund", "Lund", "Lund", "Lund", "Lund", 
"Stockholm", "Stockholm", "Stockholm", "Stockholm", "Stockholm", 
"Uppsala", "Uppsala", "Uppsala", "Uppsala", "Uppsala"), month = c("jan", 
"feb", "mar", "apr", "may", "jan", "feb", "mar", "apr", "may", 
"jan", "feb", "mar", "apr", "may"), number = c(12L, 12L, 18L, 
28L, 28L, 15L, 15L, 30L, 30L, 10L, 22L, 30L, 40L, 60L, 30L)), 
class = "data.frame", row.names = c("1", 
"2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", 
"14", "15"))

答案 1 :(得分:2)

tidyverse(实际上是dplyr)解决方案几乎等于akrun's,但是filter的数据帧而不是获取top_n

library(tidyverse)

my_data %>%
  group_by(city) %>%
  arrange(desc(number), .by_group = TRUE) %>%
  filter(row_number() %in% 1:3) %>%
  summarise(top_nr = sum(number))
## A tibble: 3 x 2
#  city      top_nr
#  <chr>      <int>
#1 Lund          74
#2 Stockholm     75
#3 Uppsala      130

答案 2 :(得分:2)

如果没有top_n(),生活可能会更简单:

dat %>%
  group_by(city) %>%
  summarize(
    top_nr = sum(tail(sort(number), 3))
    )

答案 3 :(得分:1)

感谢@akrun,但是当我运行您建议的代码时,我得到:Lund 58,它是对28、18和12的总结。我想要的是一种对Lund 28 + 28 + 18 = 74进行总结的方法。 (我发现我在上面的最初描述中犯了一个错误,对此感到抱歉)。 这是预期的(期望的)结果应为:

# A tibble: 3 x 2
  city      top_nr
  <chr>      <dbl>
1 Lund          74
2 Stockholm     75
3 Uppsala      130