如何基于字符串向量精确匹配下划线前内容筛选DataFrame列
解决方法:精确匹配下划线前的列名前缀
你的核心问题是之前的正则表达式仅匹配了前缀开头,未限制前缀后必须紧跟下划线,导致NewYork3这类带额外字符的列被误选。要实现下划线前的字符串与向量元素完全匹配,需要构造严格匹配「前缀+下划线」的正则规则。
方法一:dplyr 实现(推荐)
先把向量元素拼接成符合要求的正则表达式:给每个城市名添加开头锚点^(限定字符串起始位置)和后缀_(限定紧跟下划线),再用|分隔多个匹配项。
library(dplyr) # 模拟原始数据框 df <- data.frame( NewYork_10 = 1:5, NewYork_20 = 6:10, NewYork3_10 = 11:15, NewYork3_20 = 16:20, NewYork4_10 = 21:25, NewYork4_20 = 26:30, HongKong_10 = 31:35, HongKong_20 = 36:40, SanFrancisco_10 = 41:45, SanFrancisco_20 = 46:50 ) list_cities <- c("NewYork", "SanFrancisco") # 构造精准匹配的正则表达式 pattern <- paste0("^", list_cities, "_", collapse = "|") # 筛选目标列 new_df <- df %>% select(matches(pattern)) # 验证结果列名 colnames(new_df)
运行后会得到你需要的NewYork_10、NewYork_20、SanFrancisco_10、SanFrancisco_20四列。
方法二:Base R 实现
如果不用dplyr,也可以用基础包的grepl函数筛选列名:
pattern <- paste0("^", list_cities, "_", collapse = "|") new_df <- df[, grepl(pattern, colnames(df))]
之前写法失效的原因
matches(list_cities):直接匹配包含城市名的任意子串,NewYork3里的NewYork片段也会被命中;matches(paste0(list_cities), "_"):语法错误(未合并正则字符串),且未加开头锚点,仍会匹配中间子串;matches(paste0("^",list_cities, ".*")):仅限制开头是城市名,但.*会匹配后续任意字符(包括3_),导致NewYork3_10被误选。
内容的提问来源于stack exchange,提问作者RoyBatty
相关产品推荐
相关产品推荐

