如何创建基于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
相关产品推荐
相关产品推荐

