按组创建训练集和测试集

6

我有一个数据框,我想按组ID将其分割成训练集和测试集。以下代码会随机选取行并将它们放入训练和测试数据框中:

samp <- sample(nrow(df), 0.7 * nrow(df))
train <- df[samp, ]
test <- df[-samp, ]

然而,我想把我的ID分组在一起。
示例输入数据框 df:
my_dat <- data.frame(ID=as.factor(rep(1:3, each = 3)), Var=sample(1:100, 9))

  ID Var
  1  17
  1  26
  1 100
  2   9
  2  41
  2  49
  3  36
  3  18
  3   5

And desired output to:

Train:

  ID Var
  1  17
  1  26
  1 100
  3  36
  3  18
  3   5

测试:

  ID Var
  2   9
  2  41
  2  49

1
然后只需对id进行采样,类似于myIds <- unique(df$id); myTrainers <- sample(myIds, 2)。然后myTesters <- myIds[!(myIds %in% myTrainers)] - lmo
谢谢。不过似乎有些问题。myTrainersmyTesters 的输出分别为:[1] 2 3 Levels: 1 2 3[1] 1 Levels: 1 2 3 - apples-oranges
您的变量是一个因子变量。这就是“Levels: 1 2 3”表示的意思。如果您注意到第一部分,您会发现任务已经完成了,myTrainers得到了ID为2和3的值,而myTesters得到了ID为1的值。要将ID转换为整数,您可以使用as.integer,但您可能需要更仔细地查看该变量以及它为什么被读入为因子变量。 - lmo
1个回答

3

以下是使用 dplyr 完成此操作的一种方法:

library(tidyverse)

# Create more data to better demonstrate grouping effect
my_dat <-
  data.frame(ID = as.factor(rep(1:3, each = 9)), Var = sample(1:100, 27))

# Randomly assign train/test groups to all values of ID
groups <-
  my_dat %>%
  select(ID) %>%
  distinct(ID) %>%
  rowwise() %>%
  mutate(group = sample(
    c("train", "test"),
    1,
    replace = TRUE,
    prob = c(0.5, 0.5) # Set weights for each group here
  ))

groups

# Join group assignments to my_dat
my_dat <- my_dat %>%
  left_join(groups)

my_dat

这种方法保留了原始数据,但为每行添加了一个新列,用于定义组(训练 vs 测试)。如果您想获得仅包含训练数据的数据框,可以按照以下方式进行筛选:

filter(my_dat, group == "train")

谢谢。当我执行代码时,新列(group)仅填充了 test. 没有 training. - apples-oranges
当我使用set.seed(327)时,我看到了train、train和test的groups$group值。你看到的也是这样吗? - Andrew Brēza
1
你上次更新 dplyr 是什么时候?最近有一些重大变更。我刚刚重新安装了 dplyrtidyverse,我的代码仍然可以正常运行。我之前也遇到了你描述的问题,直到我加入了 rowwise(),它在去年六月才以其当前形式存在。 - Andrew Brēza
1
就是这样了!如果您不介意,我还有一个问题。我该如何指定训练和测试分割之间的比例?我的真实数据框架有280万行,但代码似乎将其减半了。 - apples-oranges
1
我刚刚编辑了我的答案,加入了概率加权。更改prob的两个值,以便您可以设置训练和测试的百分比。 - Andrew Brēza
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接