- R - 在data.frame中,筛选最大的组

例子数据:


set.seed(2222)


example_data <- data.frame(col1 = 1:15,


 col2 = 16:30, 


 group = sample(1:3, 15, replace = TRUE))



 col1 col2 group


1 1 16 2


2 2 17 1


3 3 18 3


4 4 19 2


5 5 20 3


6 6 21 1


7 7 22 3


8 8 23 1


9 9 24 3


10 10 25 1


11 11 26 2


12 12 27 2


13 13 28 2


14 14 29 3


15 15 30 3



我想找到记录数量最多的前n个组。

假设我想获得记录最多的前两组,


example_data %>% 


 group_by(group) %>% 


 summarise(n = n())



# A tibble: 3 x 2


 group n


 <int> <int>


1 1 4


2 2 5


3 3 6



预期的输出为:


 col1 col2 group


1 1 16 2


2 3 18 3


3 4 19 2


4 5 20 3


5 7 22 3


6 9 24 3


7 11 26 2


8 12 27 2


9 13 28 2


10 14 29 3


11 15 30 3



时间:

我们可以使用table计算每个group的频率,以decreasing顺序对它们进行sort,前2个条目的子集并过滤相应的组。


library(dplyr)



example_data %>%


 filter(group %in% names(sort(table(group), decreasing = TRUE)[1:2]))



# col1 col2 group


#1 1 16 2


#2 3 18 3


#3 4 19 2


#4 5 20 3


#5 7 22 3


#6 9 24 3


#7 11 26 2


#8 12 27 2


#9 13 28 2


#10 14 29 3


#11 15 30 3



你也可以直接在R subset中使用


subset(example_data, group %in% names(sort(table(group), decreasing = TRUE)[1:2]))



我们可以使用tidyverse方法。


library(dplyr)


example_data %>% 


 add_count(group) %>% 


 arrange(n) %>%


 filter(group %in% tail(unique(group), 2)) %>%


 select(-n)


# A tibble: 11 x 3


# col1 col2 group


# <int> <int> <int>


# 1 1 16 2


# 2 4 19 2


# 3 11 26 2


# 4 12 27 2


# 5 13 28 2


# 6 3 18 3


# 7 5 20 3


# 8 7 22 3


# 9 9 24 3


#10 14 29 3


#11 15 30 3



或者使用data.table


library(data.table)


setDT(example_data)[group %in% example_data[, .N, group][order(-N), head(group, 2)]]



使用dplyr,你还可以执行以下操作:


example_data %>%


 add_count(group) %>%


 filter(dense_rank(desc(n)) <= 2) %>%


 select(-n)



 col1 col2 group


 <int> <int> <int>


 1 1 16 2


 2 3 18 3


 3 4 19 2


 4 5 20 3


 5 7 22 3


 6 9 24 3


 7 11 26 2


 8 12 27 2


 9 13 28 2


10 14 29 3


11 15 30 3



或者:


example_data %>%


 add_count(group) %>%


 slice(which(dense_rank(desc(n)) <= 2)) %>%


 select(-n)



另一个dplyr方法可能是:


example_data %>% 


 group_by(group) %>% 


 count() %>% 


 ungroup() %>% 


 top_n(n = 2, wt = n) %>% 


 select(-n) %>% 


 inner_join(example_data)



另一个解决方案


library(dplyr)



example_data %>% 


 inner_join(


 count(., group) %>% top_n(2, n) %>% dplyr::select(group)


 )



# col1 col2 group


# 1 1 16 2


# 2 3 18 3


# 3 4 19 2


# 4 5 20 3


# 5 7 22 3


# 6 9 24 3


# 7 11 26 2


# 8 12 27 2


# 9 13 28 2


# 10 14 29 3


# 11 15 30 3



...