给定一个包含名为group
的列的数据框df
,如何在dplyr中随机抽取k
个组?它应该从中返回所有来自k
个组的行(假设df$group
中至少有k
个唯一值),并且df
中的每个组被返回的概率应该相等。
只需使用sample()
函数选择若干组即可
iris %>% filter(Species %in% sample(levels(Species),2))
如果您正在使用dplyr,我认为这种方法最有意义:
iris_grouped <- iris %>%
group_by(Species) %>%
nest()
产生的结果是:
# A tibble: 3 x 2
Species data
<fct> <list>
1 setosa <tibble [50 × 4]>
2 versicolor <tibble [50 × 4]>
3 virginica <tibble [50 × 4]>
你可以使用sample_n
来处理:
iris_grouped %>%
sample_n(2)
# A tibble: 2 x 2
Species data
<fct> <list>
1 virginica <tibble [50 × 4]>
2 versicolor <tibble [50 × 4]>
unnest()
进行进一步计算。 - Marcotidyr 1.2.0
和 dplyr 1.0.9
,@AdamLeePerelman 的回答和建议都无效。我发现 iris %>% group_by(Species) %>% nest() %>% ungroup() %>% slice_sample(n=2)
是可行的。 - Cole Robertsonlibrary(tidyverse)
sample_n_of <- function(data, size, ...) {
dots <- quos(...)
group_ids <- data %>%
group_by(!!! dots) %>%
group_indices()
sampled_groups <- sample(unique(group_ids), size)
data %>%
filter(group_ids %in% sampled_groups)
}
set.seed(1234)
mpg %>%
sample_n_of(size = 2, model)
#> # A tibble: 12 x 11
#> manufacturer model displ year cyl trans drv cty hwy fl class
#> <chr> <chr> <dbl> <int> <int> <chr> <chr> <int> <int> <chr> <chr>
#> 1 audi a6 qua~ 2.8 1999 6 auto(l~ 4 15 24 p midsi~
#> 2 audi a6 qua~ 3.1 2008 6 auto(s~ 4 17 25 p midsi~
#> 3 audi a6 qua~ 4.2 2008 8 auto(s~ 4 16 23 p midsi~
#> 4 ford mustang 3.8 1999 6 manual~ r 18 26 r subco~
#> 5 ford mustang 3.8 1999 6 auto(l~ r 18 25 r subco~
#> 6 ford mustang 4 2008 6 manual~ r 17 26 r subco~
#> 7 ford mustang 4 2008 6 auto(l~ r 16 24 r subco~
#> 8 ford mustang 4.6 1999 8 auto(l~ r 15 21 r subco~
#> 9 ford mustang 4.6 1999 8 manual~ r 15 22 r subco~
#> 10 ford mustang 4.6 2008 8 manual~ r 15 23 r subco~
#> 11 ford mustang 4.6 2008 8 auto(l~ r 15 22 r subco~
#> 12 ford mustang 5.4 2008 8 manual~ r 14 20 p subco~
请注意,使用dplyr
比普通数据框操作要慢得多:
library(microbenchmark)
microbenchmark(dplyr= iris %>% filter(Species %in% sample(levels(Species),2)),
base= iris[iris[["Species"]] %in% sample(levels(iris[["Species"]]), 2),])
Unit: microseconds
expr min lq mean median uq max neval cld
dplyr 660.287 710.655 753.6704 722.629 771.2860 1122.527 100 b
base 83.629 95.032 110.0936 106.057 119.1715 199.949 100 a
注意:虽然两者都可以使用,但[[
已知比$
更快。
我也遇到了使用nest时出现的问题。但是当我更新为最新版本的nest()、unnest()和slice_sample()语法后,它就能正常工作了。
下面是另一种版本,如果输入框架按组变量排列,则将产生相同的答案。否则,平均而言,答案也将是一样好的。这个版本比嵌套版本有一些优点:1. 最终数据框中的列按原始顺序排列;相比之下,嵌套版本将把分组变量放在第一位。2:当您进行调试时,中间结果要容易阅读得多,因为它们是普通的列表。
我想对原始组数进行有放回的采样,就像集群引导一样。可以很容易地添加更多参数,使函数更加通用。
# function to compute a clustered bootstrap sample
samplebygroups <- function(df, groupvar){
datalist <- df %>%
group_by({{ groupvar }}) %>%
group_split
n <- length(datalist)
samplegroups <- sample(n, replace = TRUE)
datalist[samplegroups] %>%
bind_rows
}
smallcars <- mtcars %>%
rownames_to_column(var = "Model") %>%
tail(5) %>%
arrange(cyl) %>%
select(Model, cyl, mpg)
set.seed(1000)
samplebygroups(smallcars, cyl)
带有输出
# A tibble: 5 x 3
Model cyl mpg
<chr> <dbl> <dbl>
1 Ford Pantera L 8 15.8
2 Maserati Bora 8 15
3 Ferrari Dino 6 19.7
4 Ford Pantera L 8 15.8
5 Maserati Bora 8 15
?sample_n
。 - SymbolixAU