如何运用DRY原则简化R中重复的数据处理代码?
简化R代码实现DRY原则的解决方案
问题核心
批量生成var3_*列:当对应var1_*为1时,取值为var2_*,否则为0,替代重复的case_when代码。
方法1:across+字符串匹配(贴合tidyverse风格)
library(tidyverse) data %<>% mutate(across(starts_with("var1_"), # 用当前var1列名替换得到对应var2列,相乘实现逻辑 ~ .x * pull(., str_replace(cur_column(), "var1", "var2")), # 生成var3_*列名,保留原后缀 .names = "var3_{str_remove(.col, 'var1_')}"))
方法2:矩阵直接运算(简洁高效)
因为var1_*是0/1变量,直接和var2_*列相乘即可满足需求,无需条件判断:
# 批量生成目标列名 var3_names <- sprintf("var3_%02d", 1:10) # 直接对列矩阵做元素乘法 data[var3_names] <- data[, starts_with("var1_")] * data[, starts_with("var2_")]
方法3:purrr::map2批量处理列对
适合需要更复杂逻辑扩展的场景:
# 提取对应列名组 var1_cols <- str_subset(names(data), "^var1_") var2_cols <- str_replace(var1_cols, "^var1", "var2") var3_cols <- str_replace(var1_cols, "^var1", "var3") # 配对处理每一组列 data[var3_cols] <- map2_dfc(data[var1_cols], data[var2_cols], ~ .x * .y)
原尝试代码的问题说明
isTRUE(.x==1)错误:.x是整列向量,isTRUE会将整个向量转为单个布尔值,无法实现逐元素判断;- 赋值逻辑错误:
across的函数参数应返回计算后的向量,而非直接赋值操作; .names参数使用不当:{numbers}无法匹配列的对应后缀,应基于原列名动态生成。
内容的提问来源于stack exchange,提问作者Anthony Romero
相关产品推荐
相关产品推荐

