You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何按分组完整抽取数据集子集?以team分组抽25%数据为例

按分组完整抽样拆分DataFrame

我有一个DataFrame,需要拆分为原数据量75%和25%的两部分。要求抽样时保留team分组的完整性——比如示例数据里有8个team,要随机抽取2个完整的team作为25%的子集。

我试了用dplyr的slice_sample写代码:

testdata <- df %>% group_by(team) %>% slice_sample(n = 2)

但这段代码是每个team里抽2行,完全不符合我的需求。

数据示例

team points assists
1     1     99      33
2     1     90      28
3     1     86      31
4     1     88      39
5     2     95      34
6     2     92      30
7     2     91      32
8     2     79      35
9     3     85      36
10    3     90      29
11    3     91      24
12    3     97      26
13    4     96      28
14    4     94      18
15    4     95      19
16    4     98      25
17    5     78      36
18    5     80      34
19    5     85      39
20    5     89      33
21    6     94      34
22    6     85      39
23    6     99      28
24    6     79      31
25    7     78      35
26    7     99      29
27    7     98      36
28    7     75      39
29    8     97      33
30    8     68      26
31    8     86      38
32    8     76      31

错误代码的执行结果

team points assists
   <dbl>  <dbl>   <dbl>
 1     1     90      28
 2     1     99      33
 3     2     95      34
 4     2     92      30
 5     3     91      24
 6     3     85      36
 7     4     95      19
 8     4     98      25
 9     5     80      34
10     5     78      36
11     6     85      39
12     6     94      34
13     7     78      35
14     7     98      36
15     8     76      31
16     8     86      38

DataFrame结构

structure(list(team = c(1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 
4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8), points = c(99, 
90, 86, 88, 95, 92, 91, 79, 85, 90, 91, 97, 96, 94, 95, 98, 78, 
80, 85, 89, 94, 85, 99, 79, 78, 99, 98, 75, 97, 68, 86, 76), 
    assists = c(33, 28, 31, 39, 34, 30, 32, 35, 36, 29, 24, 26, 
    28, 18, 19, 25, 36, 34, 39, 33, 34, 39, 28, 31, 35, 29, 36, 
    39, 33, 26, 38, 31)), class = "data.frame", row.names = c(NA, 
-32L))
解决方案

要实现按完整分组抽样,核心思路是先随机抽取分组(team),再根据选中的分组筛选原数据。

方法1:分步实现

library(dplyr)

# 提取所有唯一team,随机抽取2个
selected_teams <- df %>% 
  distinct(team) %>% 
  slice_sample(n = 2)

# 筛选选中team的全部数据作为25%子集
subset_25 <- df %>% 
  filter(team %in% selected_teams$team)

# 剩余数据为75%主数据集
subset_75 <- df %>% 
  filter(!team %in% selected_teams$team)

方法2:链式简洁写法

# 一步生成25%子集
subset_25 <- df %>%
  inner_join(
    df %>% distinct(team) %>% slice_sample(n = 2),
    by = "team"
  )

# 生成75%子集
subset_75 <- anti_join(df, subset_25, by = "team")

逻辑解释

  • distinct(team):提取所有不重复的分组标识,这里是8个team
  • slice_sample(n = 2):从分组列表中随机抽取2个,保证分组完整性
  • 用filter或inner_join/anti_join筛选对应分组的全部数据,最终子集的总数据量刚好是原数据的25%(每个team4行,2个team共8行,占32行的25%)

内容的提问来源于stack exchange,提问作者Beardedant

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 06:30:51