使用 dplyr 的每个组的前 "n" 行——每个组的数量不同
Top "n" rows of each group using dplyr -- with different number per group
我将使用内置的 chickwts
数据作为示例。
这是数据,有 5 种 Feed 类型。
> head(chickwts)
weight feed
1 179 horsebean
2 160 horsebean
3 136 horsebean
4 227 horsebean
5 217 horsebean
6 168 horsebean
> table(chickwts$feed)
casein horsebean linseed meatmeal soybean sunflower
12 10 12 11 14 12
我想要的是每种 Feed 类型按重量排列的前几行。但是,我需要为每种 Feed 类型分配不同的编号吗?例如,
top_n_feed <-
c(
"casein" = 3,
"horsebean" = 5,
"linseed" = 3,
"meatmeal" = 6,
"soybean" = 3,
"sunflower" = 2
)
如何使用 dplyr
执行此操作?
要按重量获取每种 Feed 类型的前 n
行,我可以使用如下代码,但我不确定如何将其扩展到每种 Feed 类型的不同数量。
chickwts %>%
group_by(feed) %>%
slice_max(order_by = weight, n = 5)
这并不是 dplyr
说起来容易的事情。我建议合并数据然后过滤。
tibble(feed=names(top_n_feed), topn=top_n_feed) %>%
inner_join(chickwts) %>%
group_by(feed) %>%
arrange(desc(weight), .by_group=TRUE) %>%
filter(row_number() <= topn) %>%
select(-topn)
另一种使用split
和map2
的方法:
library(dplyr)
library(purrr)
chickwts %>%
filter(feed %in% names(top_n_feed)) %>%
split(.$feed) %>%
map2_dfr(top_n_feed[names(.)], ~slice_max(.x, order_by = weight, n = .y))
将 top_n_feed
放入 chickwts
数据框和 select 每个组的顶部 n
行。
library(dplyr)
tibble::enframe(top_n_feed, name = 'feed') %>%
left_join(chickwts, by = 'feed') %>%
group_by(feed) %>%
top_n(first(value), weight)
# feed value weight
# <chr> <dbl> <dbl>
# 1 casein 3 390
# 2 casein 3 379
# 3 casein 3 404
# 4 horsebean 5 179
# 5 horsebean 5 160
# 6 horsebean 5 227
# 7 horsebean 5 217
# 8 horsebean 5 168
# 9 linseed 3 309
#10 linseed 3 260
# … with 12 more rows
出于某种原因,我无法使 slice_sample
适用于此示例。
每当你有一个命名列表时,想想 purrr::imap
。如果不需要,请避免连接,尤其是在大规模工作时。
library(dplyr)
library(purrr)
top_n_feed <- c(
"casein" = 3,
"horsebean" = 5,
"linseed" = 3,
"meatmeal" = 6,
"soybean" = 3,
"sunflower" = 2
)
imap_dfr(top_n_feed, ~ filter(chickwts, feed %in% .y) %>%
slice_max(order_by = weight, n = .x))
weight feed
1 404 casein
2 390 casein
3 379 casein
4 227 horsebean
5 217 horsebean
6 179 horsebean
7 168 horsebean
8 160 horsebean
9 309 linseed
10 271 linseed
11 260 linseed
12 380 meatmeal
13 344 meatmeal
14 325 meatmeal
15 315 meatmeal
16 303 meatmeal
17 263 meatmeal
18 329 soybean
19 327 soybean
20 316 soybean
21 423 sunflower
22 392 sunflower
我将使用内置的 chickwts
数据作为示例。
这是数据,有 5 种 Feed 类型。
> head(chickwts)
weight feed
1 179 horsebean
2 160 horsebean
3 136 horsebean
4 227 horsebean
5 217 horsebean
6 168 horsebean
> table(chickwts$feed)
casein horsebean linseed meatmeal soybean sunflower
12 10 12 11 14 12
我想要的是每种 Feed 类型按重量排列的前几行。但是,我需要为每种 Feed 类型分配不同的编号吗?例如,
top_n_feed <-
c(
"casein" = 3,
"horsebean" = 5,
"linseed" = 3,
"meatmeal" = 6,
"soybean" = 3,
"sunflower" = 2
)
如何使用 dplyr
执行此操作?
要按重量获取每种 Feed 类型的前 n
行,我可以使用如下代码,但我不确定如何将其扩展到每种 Feed 类型的不同数量。
chickwts %>%
group_by(feed) %>%
slice_max(order_by = weight, n = 5)
这并不是 dplyr
说起来容易的事情。我建议合并数据然后过滤。
tibble(feed=names(top_n_feed), topn=top_n_feed) %>%
inner_join(chickwts) %>%
group_by(feed) %>%
arrange(desc(weight), .by_group=TRUE) %>%
filter(row_number() <= topn) %>%
select(-topn)
另一种使用split
和map2
的方法:
library(dplyr)
library(purrr)
chickwts %>%
filter(feed %in% names(top_n_feed)) %>%
split(.$feed) %>%
map2_dfr(top_n_feed[names(.)], ~slice_max(.x, order_by = weight, n = .y))
将 top_n_feed
放入 chickwts
数据框和 select 每个组的顶部 n
行。
library(dplyr)
tibble::enframe(top_n_feed, name = 'feed') %>%
left_join(chickwts, by = 'feed') %>%
group_by(feed) %>%
top_n(first(value), weight)
# feed value weight
# <chr> <dbl> <dbl>
# 1 casein 3 390
# 2 casein 3 379
# 3 casein 3 404
# 4 horsebean 5 179
# 5 horsebean 5 160
# 6 horsebean 5 227
# 7 horsebean 5 217
# 8 horsebean 5 168
# 9 linseed 3 309
#10 linseed 3 260
# … with 12 more rows
出于某种原因,我无法使 slice_sample
适用于此示例。
每当你有一个命名列表时,想想 purrr::imap
。如果不需要,请避免连接,尤其是在大规模工作时。
library(dplyr)
library(purrr)
top_n_feed <- c(
"casein" = 3,
"horsebean" = 5,
"linseed" = 3,
"meatmeal" = 6,
"soybean" = 3,
"sunflower" = 2
)
imap_dfr(top_n_feed, ~ filter(chickwts, feed %in% .y) %>%
slice_max(order_by = weight, n = .x))
weight feed
1 404 casein
2 390 casein
3 379 casein
4 227 horsebean
5 217 horsebean
6 179 horsebean
7 168 horsebean
8 160 horsebean
9 309 linseed
10 271 linseed
11 260 linseed
12 380 meatmeal
13 344 meatmeal
14 325 meatmeal
15 315 meatmeal
16 303 meatmeal
17 263 meatmeal
18 329 soybean
19 327 soybean
20 316 soybean
21 423 sunflower
22 392 sunflower