Niv*_*vel 17 regex r gsub stringr stringi
我有以下字符串:
strings <- c("ABBSDGNHNGA", "AABSDGDRY", "AGNAFG", "GGGDSRTYHG")
Run Code Online (Sandbox Code Playgroud)
我想切断字符串,一旦A,G和N的出现次数达到一定值,比如说3.在这种情况下,结果应该是:
some_function(strings)
c("ABBSDGN", "AABSDG", "AGN", "GGG")
Run Code Online (Sandbox Code Playgroud)
我试图用stringi,stringr和正则表达式的表达式,但我无法弄清楚.
这是一个使用的基本R选项 strsplit
sapply(strsplit(strings, ""), function(x)
paste(x[1:which.max(cumsum(x %in% c("A", "G", "N")) == 3)], collapse = ""))
#[1] "ABBSDGN" "AABSDG" "AGN" "GGG"
Run Code Online (Sandbox Code Playgroud)
或者在 tidyverse
library(tidyverse)
map_chr(str_split(strings, ""),
~str_c(.x[1:which.max(cumsum(.x %in% c("A", "G", "N")) == 3)], collapse = ""))
Run Code Online (Sandbox Code Playgroud)
您可以通过str_extract对stringr包的简单调用来完成您的任务:
library(stringr)
strings <- c("ABBSDGNHNGA", "AABSDGDRY", "AGNAFG", "GGGDSRTYHG")
str_extract(strings, '([^AGN]*[AGN]){3}')
# [1] "ABBSDGN" "AABSDG" "AGN" "GGG"
Run Code Online (Sandbox Code Playgroud)
[^AGN]*[AGN]正则表达式模式的部分表示要查找零个或多个不是A,G或N的连续字符,然后是A,G或N的一个实例.带括号和括号的附加包装(如下所示([^AGN]*[AGN]){3})表示对于那种模式连续三次.您可以通过更改花括号中的整数来更改要查找的A,G,N的出现次数:
str_extract(strings, '([^AGN]*[AGN]){4}')
# [1] "ABBSDGNHN" NA "AGNA" "GGGDSRTYHG"
Run Code Online (Sandbox Code Playgroud)
使用基本R函数可以通过几种方法完成任务.一个是使用regexpr后跟regmatches:
m <- regexpr('([^AGN]*[AGN]){3}', strings)
regmatches(strings, m)
# [1] "ABBSDGN" "AABSDG" "AGN" "GGG"
Run Code Online (Sandbox Code Playgroud)
或者,您可以使用sub:
sub('(([^AGN]*[AGN]){3}).*', '\\1', strings)
# [1] "ABBSDGN" "AABSDG" "AGN" "GGG"
Run Code Online (Sandbox Code Playgroud)
识别模式的位置,gregexpr然后使用提取第n个位置(3)并将所有内容从1第n个位置到第n个位置subset.
nChars <- 3
pattern <- "A|G|N"
# Using sapply to iterate over strings vector
sapply(strings, function(x) substr(x, 1, gregexpr(pattern, x)[[1]][nChars]))
Run Code Online (Sandbox Code Playgroud)
PS:
如果有一个没有3个匹配项的字符串,它将生成NA,所以你只需要na.omit在最终结果上使用它.