我想使用每个组中不相等的样本大小从数据框中对行进行采样。
假设我们有一个按“组”分组的简单数据框:
library(dplyr)
set.seed(123)
df <- data.frame(group = rep(c("A", "B"), each = 10),
value = rnorm(10))
df
#> group value
#> 1 A -0.56047565
#> 2 A -0.23017749
#> .....
#> 10 A -0.44566197
#> 11 B -0.56047565
#> 12 B -0.23017749
#> .....
#> 20 B -0.44566197
Run Code Online (Sandbox Code Playgroud)
使用包中的slice_sample函数dplyr,您可以轻松地从此数据框中切出相同大小的组:
df %>% group_by(group) %>% slice_sample(n = 2) %>% ungroup()
#> # A tibble: 4 x 2
#> group value
#> <fct> <dbl>
#> 1 A -0.687
#> 2 A -0.446
#> 3 B -0.687
#> 4 B 1.56
Run Code Online (Sandbox Code Playgroud)
题
您如何从每个组(大小不等的切片组)中采样不同数量的值?例如,从 A 组中抽取 4 行,从 B 组中抽取 5 行?
小智 11
我能想到的最简单的事情是map2使用purrr.
library(dplyr)
library(purrr)
df %>%
group_split(group) %>%
map2_dfr(c(4, 5), ~ slice_sample(.x, n = .y))
Run Code Online (Sandbox Code Playgroud)
# A tibble: 9 x 2
group value
<chr> <dbl>
1 A -0.687
2 A 1.56
3 A 0.0705
4 A 1.72
5 B -0.560
6 B 0.461
7 B 0.129
8 B 0.0705
9 B -0.230
Run Code Online (Sandbox Code Playgroud)
需要注意的是,您需要了解拆分的顺序。我认为group_split()将按照因素对组进行排序。解决这个问题的方法是像这样进行调整,并n从命名向量中查找 。
group_slice_n <- c(A = 4, B = 5)
df %>%
split(.$group) %>%
imap_dfr(~ slice_sample(.x, n = group_slice_n[.y]))
Run Code Online (Sandbox Code Playgroud)
尝试这个:
group_sizes <- tibble(group = c("A", "B"), size = c(4, 5))
set.seed(2021)
df %>%
left_join(group_sizes, by = "group") %>%
group_by(group) %>%
mutate(samp = sample(n())) %>%
filter(samp <= size) %>%
ungroup()
# # A tibble: 9 x 4
# group value size samp
# <chr> <dbl> <dbl> <int>
# 1 A 0.0705 4 2
# 2 A 0.129 4 4
# 3 A -0.687 4 1
# 4 A -0.446 4 3
# 5 B -0.560 5 5
# 6 B 1.56 5 1
# 7 B 0.129 5 4
# 8 B 1.72 5 3
# 9 B -1.27 5 2
Run Code Online (Sandbox Code Playgroud)