如何让match()忽略元素内部分段顺序匹配两个字符串向量?
问题:匹配反转分隔符的字符串向量,得到指定输出
我需要用match()匹配两个字符串向量first和second1,执行代码(desired_output = match(first, second1))能得到输出#> [1] 4 5 1 6 2 3。但second1里的字符串元素可能会被反转两部分(比如"perf.acog"变成"acog.perf"),也就是second2的形式。现在要实现:让match(first, second2)得到和match(first, second1)完全相同的输出。
注意:字符串两部分的分隔符是"[^[:alnum:]]+"定义的任意符号,比如.、_等,需要通用可行的解决方案。
相关向量定义如下:
first = c("asom.acog", "conf.acog", "perf.acog", "conf.asom", "perf.asom", "perf.conf") second1 = c("perf.acog", "perf.asom", "perf.conf", "asom.acog", "conf.acog", "conf.asom") second2 = c("acog.perf", "asom.perf", "conf.perf", "acog.asom", "acog.conf", "asom.conf")
解决方案
核心思路是将每个字符串的两部分拆分后排序,再重新拼接成统一格式,这样反转前后的字符串会被标准化为同一形式,再执行match即可得到目标输出。
具体代码实现:
# 定义字符串标准化函数 standardize_str <- function(x) { # 按任意非字母数字分隔符拆分字符串 parts <- strsplit(x, "[^[:alnum:]]+") # 对拆分后的两部分排序,再用点号拼接(统一格式) sapply(parts, function(p) paste(sort(p), collapse = ".")) } # 对向量标准化后执行匹配 result <- match(standardize_str(first), standardize_str(second2)) print(result) #> [1] 4 5 1 6 2 3
说明
strsplit(x, "[^[:alnum:]]+")可以适配任意非字母数字分隔符(比如.、_、-等),准确拆分字符串的两部分;- 对拆分后的部分排序再拼接,能让
"perf.acog"和"acog.perf"这类反转字符串变成完全一致的标准化形式; - 标准化后的向量执行
match,就能得到和match(first, second1)完全相同的结果。
内容的提问来源于stack exchange,提问作者Simon Harmel
相关产品推荐
相关产品推荐

