如何用dplyr的select仅对指定列子集按条件筛选并保留其他列?
解决dplyr select仅针对特定列子集移除全0列的问题
你需要仅对特定列子集(比如cx1_、cx2_开头的列)执行「移除全0列」的筛选,同时保留其他所有列(包括本身全0的id3)。你之前尝试的.cols参数无效,因为where()函数本身不支持这个参数,正确的做法是把列选择逻辑拆分成两部分:
- 保留所有不在目标筛选子集里的列
- 对目标子集里的列,筛选出非全0的列
示例数据
data <- data.frame( name1 = c("a", "b", "c", "d", "e"), name2 = c(6, 7, 4, 5, 5), id3 = c(0, 0, 0, 0, 0), cx1_a = c(0, 0, 0, 0, 0), cx1_b = c(1, 2, 0, 0, 0), cx2_a = c(0, 0, 1, 1, 0), cx2_b = c(4, 5, 0, 0, 0) )
解决方案1:逻辑选择拆分列
最直观的写法,明确拆分保留列和筛选列:
library(dplyr) data_cleaned <- data %>% select( # 保留所有不是cx1_或cx2_开头的列 !starts_with("cx1_") & !starts_with("cx2_"), # 对cx1_/cx2_开头的列,仅保留非全0的 (starts_with("cx1_") | starts_with("cx2_")) & where(~sum(.) != 0) )
解决方案2:正则简化目标列匹配
如果目标列的命名有规律,可以用matches()简化正则匹配:
data_cleaned <- data %>% select( # 保留所有不匹配^cx[12]_的列 !matches("^cx[12]_"), # 匹配^cx[12]_且非全0的列 matches("^cx[12]_") & where(~sum(.) != 0) )
验证结果
执行后data_cleaned的列会是:name1、name2、id3、cx1_b、cx2_a、cx2_b,成功移除了全0的cx1_a,同时保留了全0的id3。
内容的提问来源于stack exchange,提问作者Maxime Buron
相关产品推荐
相关产品推荐

