用grepl筛选指定列范围外的列名?解决R代码报错问题
问题描述
我有一个数据框df,其列名如下:
[1] "lab_id" "weeks" "group" [4] "level" "id_row" "id" [7] "number" "tube" "dp" [10] "time" "label" "age" [13] "gender" "wtspike_ab1" "wtrbd_ab1" [16] "wts1_ab1" "wts2_ab1" "wtntd_ab2" [19] "wtn_ab2" "alphaspike_ab2" "alpharbd_ab2" [22] "betaspike_ab2" "betarbd_ab2" "gammaspike_ab2"
我的目标是通过列名筛选该数据框,使用了以下方法:
test1 <- test[, test <- grepl('wtspike|wtrbd|wts1|wts2|wtntd|wtn', colnames(test))]
这段代码可筛选匹配模式的列名,但会移除前14列元数据。因此我尝试用以下代码避免对前14列执行筛选操作:
filtered_test <- test[, 1:14(test) & grepl('wtspike|wtrbd|wts1|wts2|wtntd|wtn', colnames(test))]
但出现报错:
Error: attempt to apply non-function
我想咨询:
- 有没有更好的替代方法实现该筛选操作?
- 我的代码出现该报错的原因是什么?
解答
1. 实现筛选的替代方法
要保留前14列元数据,同时筛选出列名匹配指定模式的其他列,有几种简洁可靠的方式:
方法一:逻辑向量合并法
先生成一个逻辑向量,前14位设为TRUE(保留所有元数据列),剩余列用grepl判断是否匹配目标模式,最后用这个向量筛选数据框:
# 构建筛选逻辑:前14列全保留,后面列匹配模式才保留 keep_logic <- c(rep(TRUE, 14), grepl('wtspike|wtrbd|wts1|wts2|wtntd|wtn', colnames(test)[-c(1:14)])) # 执行筛选 filtered_test <- test[, keep_logic]
方法二:分组合并法
直接拆分出元数据列和目标匹配列,再合并成新数据框:
# 提取前14列元数据 meta_part <- test[, 1:14] # 提取列名匹配模式的列 target_part <- test[, grepl('wtspike|wtrbd|wts1|wts2|wtntd|wtn', colnames(test))] # 合并两部分 filtered_test <- cbind(meta_part, target_part)
方法三:dplyr简洁语法
如果习惯使用dplyr包,可以用更直观的语法完成筛选:
library(dplyr) filtered_test <- test %>% select(1:14, matches('wtspike|wtrbd|wts1|wts2|wtntd|wtn'))
2. 报错原因分析
你写的1:14(test)是错误的语法:
1:14是R中生成整数序列的语法,它本身不是函数,后面加(test)会被R误认为是调用函数的操作,因此抛出attempt to apply non-function(尝试应用非函数)的错误。- 正确的逻辑应该是构建一个包含前14位
TRUE的逻辑向量,再和后续列的匹配结果合并,而不是用&直接连接错误的序列写法。
内容的提问来源于stack exchange,提问作者Someone_1313
相关产品推荐
相关产品推荐

