如何在 dplyr 中按组查找前 N 个降序值

8
我有一个在R中的以下数据框。
  Serivce     Codes
   ABS         RT
   ABS         RT
   ABS         TY
   ABS         DR
   ABS         DR
   ABS         DR
   ABS         DR
   DEF         RT
   DEF         RT
   DEF         TY
   DEF         DR
   DEF         DR
   DEF         DR
   DEF         DR
   DEF         TY
   DEF         SE
   DEF         SE

我想要的是按服务分类的代码数量,以降序排列。
  Serivce     Codes    Count
   ABS         DR        4
   ABS         RT        2 
   ABS         TY        1
   DEF         DR        4
   DEF         RT        2
   DEF         TY        2  

我正在R语言中进行以下操作。
df%>% 
group_by(Service,Codes) %>% 
summarise(Count = n()) %>%
top_n(n=3,wt = Count) %>% 
arrange(desc(Count)) %>% 
as.data.frame()   

但是它没有给我想要的内容。
3个回答

10

我们可以尝试使用 count/arrange/slice

df1 %>% 
   count(Service, Codes) %>%
   arrange(desc(n)) %>% 
   group_by(Service) %>% 
   slice(seq_len(3))
# A tibble: 6 x 3
# Groups:   Service [2]
#  Service Codes     n
#    <chr> <chr> <int>
#1     ABS    DR     4
#2     ABS    RT     2
#3     ABS    TY     1
#4     DEF    DR     4
#5     DEF    RT     2
#6     DEF    SE     2
在原帖中,我们还需要按 'Service' 进行排序。正如 @Marius 在评论中提到的那样,如果存在并列情况,则 top_n 将包含更多行。一种选项是使用 'Service' 进行第二次分组并使用 slice(如上所示),或在分组后,我们可以使用 filter 进行筛选。
df1 %>% 
  group_by(Service,Codes) %>%
  summarise(Count = n()) %>%
  top_n(n=3,wt = Count)  %>%
  arrange(Service, desc(Count)) %>%
  group_by(Service) %>%
  filter(row_number() <=3)

完美运行。我只是想知道为什么我的方法不起作用? - Neil
@Neil 更新了帖子。 - akrun
1
@Neil,你在原始代码中每个组中获得了超过3行,因为如果存在并列,则top_n会包括超过n行。 - Marius
1
@Neil,正如Marius所说,这里的问题在于ties。因此,您可以添加df1 %>% group_by(Service,Codes) %>% summarise(Count = n()) %>%top_n(n=3,wt = Count) %>% group_by(Service) %>% slice(seq_len(3)) - akrun

1

df%>% count(Service,Codes) %>% mutate(rank = dense_rank(desc(n))) %>% filter(rank < 5)

在返回前n行的数量时,类似于row_number()

n是按Service、Codes分组计数


0
在基本的R语言中,你可以用两行代码实现这个功能。
# get data.frame of counts by service-code pairs
mydf <- data.frame(table(dat))

# get top 3 by service
do.call(rbind, lapply(split(mydf, mydf$Serivce), function(x) x[order(-x$Freq)[1:3],]))

这将返回

      Serivce Codes Freq
ABS.1     ABS    DR    4
ABS.3     ABS    RT    2
ABS.7     ABS    TY    1
DEF.2     DEF    DR    4
DEF.4     DEF    RT    2
DEF.6     DEF    SE    2

第一行使用table获取计数,然后转换为data.frame。第二行,按服务拆分,按order的负值排序,并提取前三个元素。将结果与do.call组合。


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