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

编写支持group_by的友好型R函数:自定义验证列生成求助

优化分组数据的训练/验证集拆分函数

核心优化思路

放弃使用已逐步弃用的do(),转而利用dplyr的分组上下文自动特性,结合mutate或group_modify()实现兼容分组/非分组数据的流畅管道函数。


方案1:极简通用版(兼容分组与非分组)

dplyr在分组数据中调用n()时,会自动识别为组内行数;非分组时则返回总行数,因此无需额外判断即可实现通用拆分:

split_train_val <- function(data, train_prop = 0.75) {
  data %>%
    dplyr::mutate(
      # 按比例随机分配训练集标记
      training = sample(c(TRUE, FALSE), 
                       size = dplyr::n(), 
                       replace = TRUE, 
                       prob = c(train_prop, 1 - train_prop)),
      # 验证集与训练集互斥
      validation = !training
    )
}

使用示例:

  • 非分组数据:mtcars %>% split_train_val()
  • 分组数据:mtcars %>% dplyr::group_by(cyl) %>% split_train_val()

方案2:带精细控制的进阶版

如果需要限制每组训练集的最小样本量(避免小分组拆分后样本不足),可以用group_modify()实现:

split_train_val <- function(data, train_prop = 0.75, min_train = 2) {
  data %>%
    dplyr::group_modify(function(group, ...) {
      n_group <- nrow(group)
      # 确保训练集样本数不低于设定最小值
      train_n <- max(floor(train_prop * n_group), min_train)
      train_idx <- sample(n_group, train_n)
      
      group %>%
        dplyr::mutate(
          training = dplyr::row_number() %in% train_idx,
          validation = !training
        )
    }) %>%
    dplyr::ungroup() # 可选:根据需求保留/取消分组状态
}

为什么if()+do()会失败?

do()的语法逻辑与现代dplyr管道风格不兼容,容易出现上下文环境混淆(比如变量引用、分组识别出错)。而mutate/group_modify()是为分组数据操作设计的原生函数,能自动适配分组上下文,代码更简洁可靠。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 08:07:40