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

如何创建基于dplyr的可复用R函数 实现多次便捷数据操作与子集提取

问题修正方案

原有代码的核心问题

  • dplyr::matches()的正则规则错误:你写的匹配规则"tib | lum | tho"包含多余空格,而实际列名(如x_tib_1)中没有对应空格,无法命中任何目标列
  • select()中直接使用ifelse的逻辑错误:ifelse是向量化运算函数,返回长度和输入一致的向量,不能用来返回动态的列选择规则
  • 函数硬编码全局数据集data,复用性低,建议将数据集作为参数传入函数

修正后的完整代码

library(tidyverse)

# 模拟数据
data <- tibble(
  p = rep("Par_1", 40),
  v = c(rep("slo", 20), rep("mod", 20)),
  n = c(rep(1, 10), rep(2, 10), rep(1, 10), rep(2, 10)),
  r = c(rep(800, 5), rep(100, 5), rep(800, 5), rep(100, 5),
        rep(800, 5), rep(100, 5), rep(800, 5), rep(100, 5)),
  x_tib_1 = runif(40, min = .100, max = .300),
  x_lum_1 = runif(40, min = .100, max = .300),
  x_tho_1 = runif(40, min = .100, max = .300),
  x_sen_1 = runif(40, min = .100, max = .300),
  x_ves_1 = runif(40, min = .100, max = .300),
)

# 修正后的处理函数
test_function <- function(input_data, x, y, z){
  
  output <- input_data %>%
    filter(v == x, n == y, r == z) %>%
    # 条件选列:用常规if判断替代ifelse
    select(
      p,
      if (z == 800) {
        matches("tib|lum|tho") # 去掉多余空格即可命中目标列
      } else {
        x_tib_1:x_ves_1 # 直接用列范围写法更清晰,不需要写索引
      }
    ) %>%
    group_by(p) %>%
    summarise(across(where(is.numeric), mean, na.rm = TRUE)) %>% # 推荐用across替代已废弃的summarise_all
    mutate(across(where(is.numeric), round, 3))
  
  return(output)
}

# 测试函数
test <- test_function(data, "slo", 1, 800)

调整说明

  • 正则匹配去掉了多余空格,"tib|lum|tho"可以正确命中包含对应字符的列
  • 用常规if判断实现动态选列,符合dplyr的非标准评估规则
  • 替换了已被官方弃用的summarise_all,改用across写法适配更高版本的dplyr
  • 新增input_data参数,函数可以适配任意同结构数据集,不需要依赖全局变量

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 23:06:01