首页 > 解决方案 > 某些数据大小小于 2 的数据列表中的 sample_n(2, replace=F) 存在问题

问题描述

我在 R 中的 'dplyr' 中需要 sample_n() 的帮助:我有一个数据列表,列表的riskset[[1]], riskset[[2]],..., riskset[[1000]])每个元素riskset[[i]]都是观察的数据框,我riskset根据分布将每个观察分为 1:4 组一个变量。所以里面的数据是riskset[[i]]这样的:

id      sex        grp      ...
1        F          1       ...
2        M          3       ...
3        F          1       ...
4        M          4       ...
5        F          2       ...
6        F          3       ...
......................

我想从每个风险集中的每个 grp 中抽取 2 个观察值并将它们保存为样本列表。我用了 sample<- list()

for(i in 1:1000){
sample[[i]] <- riskset[[i]] %>% group_by(grp) %>% sample_n(2,replace=F)
}

它给了我错误:

size must be less or equal than 1 (size of data), set ‘replace = TRUE’ to use sampling with replacement.

我在每个grp中有超过2个obs的风险集上尝试了代码,它起作用了。但它不适用于某些组中少于 2 个 obs 的风险集。对于少于 2 个 obs 的组,我想要它拥有的所有 obs。对于拥有超过 2 个 obs 的组,我想在不替换的情况下对 2 个 obs 进行采样。如何使用 R 函数实现采样目标?提前致谢!

标签: rdplyrsampling

解决方案


我们可以使用map循环list('riskset'),然后按'grp'分组,应用sample_n

library(tidyerse)
out <- map(riskset, ~ .x  %>%
                    group_by(grp) %>%
                    sample_n(pmin(n(), 2), replace = TRUE))

或者另一种选择是slice

map(riskset, ~ .x %>%
                  group_by(grp) %>%
                  slice(if(n() < 2) 1 else sample(row_number(), 2))

或不使用if/else

map(riskset, ~ .x %>%
                  group_by(grp) %>%
                  slice(sample(seq_len(pmin(n(), 2)))))

数据

iris1 <-  iris %>%
               select(grp = Species, everything()) %>%
               slice(c(1:5, 51))
riskset <- list(iris1, iris1)

推荐阅读