R语言如何简洁提取字符向量各元素的第3个单词
提取字符向量每个元素第3个单词的简洁实现
问题背景
现有名为strains的字符向量,前10个元素内容如下:
head(strains, 10) [1] "Lactobacillus gasseri APC678" "Lactobacillus gasseri DSM 20243" [3] "Bifidobacterium angulatum B677" "Bifidobacterium breve Reuter S1" [5] "Lactobacillus reuteri F275" "Lactobacillus acidophilus L917" [7] "Lactobacillus acidophilus 4357" "Bifidobacterium pseudocatenulatum B1279" [9] "Bifidobacterium longum subsp. infantis JCM 1210" "Clostridium difficile 43594"
需求为提取每个元素的第3个单词组成新向量,例如元素"Lactobacillus gasseri APC678"仅保留"APC678"。
原有实现代码如下(注意包名存在笔误,正确包名为tidyverse):
library(tidyverse) lapply(strains %>% str_split(" "), '[', 3) %>% unlist
该代码可以得到正确结果,输出如下:
[1] "APC678" "DSM" "B677" "Reuter" "F275" "L917" "4357" "B1279" "subsp." "43594" "subsp." "F275" "1SL4" "JCM" [15] "JCM" "AM63" "DSM" "L917" "61D" "Bb14" "AM63" "VPI"
现需要更优雅简洁的实现方案,例如基于正则的实现。
本次示例数据可通过如下代码复现:
strains <- c("Lactobacillus gasseri APC678", "Lactobacillus gasseri DSM 20243", "Bifidobacterium angulatum B677", "Bifidobacterium breve Reuter S1", "Lactobacillus reuteri F275", "Lactobacillus acidophilus L917", "Lactobacillus acidophilus 4357", "Bifidobacterium pseudocatenulatum B1279", "Bifidobacterium longum subsp. infantis JCM 1210", "Clostridium difficile 43594" )
实现方案
- 方案1:简化字符串拆分逻辑(tidyverse)
利用str_split的simplify参数直接返回矩阵,无需lapply和unlist操作,逻辑和原有思路一致但更简洁,同时适配多空格分隔的场景:
library(tidyverse) str_split(strains, "\\s+", simplify = TRUE)[, 3]
- 方案2:正则直接提取(tidyverse)
无需拆分字符串,通过正则直接匹配第三个连续非空白片段,代码更简洁,长向量下性能更好:
library(tidyverse) # 匹配前两个非空字段+空白分隔符,捕获第三个非空字段 str_extract(strains, "^\\S+\\s+\\S+\\s+(\\S+)", group = 1)
- 方案3:基础R正则实现(零依赖)
不需要加载任何第三方包,直接用基础R的sub函数完成替换提取,适配多空格场景:
sub("^\\S+\\s+\\S+\\s+(\\S+).*", "\\1", strains)
以上三种方案输出结果和原有实现完全一致。
内容的提问来源于stack exchange,提问作者bpvalderrama
相关产品推荐
相关产品推荐

