解析字符串并将其拆分为 R

Parsing String and splitting it in R

我在处理 R 中的字符串时遇到了正则表达式问题。

我有 RNAfold 软件提供的数据结构,如下所示:

".....(((..((((((((.((((((((((.........))))))) )))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))

这是 miRNA 的典型二级结构,但我还有其他不是 miRNA 的序列,看起来有点像这样:

...((((.....))))................((((((...((..(((. .((((...((((((.....)))))))...)))))))))))...))))))) ......

第二个序列有两个发夹循环,一个在开头,另一个在中间,而第一个序列在中间只有一个发夹循环。

点(“.”)表示未配对的核苷酸,而“(”表示与其对应物配对的核苷酸,表示为“)”。

我想拆分这个字符串,这样我就可以得到结构中的词干。

我想要得到的输出是:

输入:

[1] "....(((..((((((((.(((((((((((.........))))))))))).))))))))..))).."

输出:

[1] "....(((..((((((((.(((((((((((........."
[2] "))))))))))).))))))))..))).."

这样我就可以统计拆分字符串的数量和词干的数量了。

第二个序列的结果将是:

输入:

[1] ...((((.....))))...........(((((((...((..(((..((((...((((((.....)))).))...)))).))).))...))))))).......

输出:

[1] "...((((....."
[2] "))))...........(((((((...((..(((..((((...((((((....."
[3] ")))).))...)))).))).))...)))))))......."

所以在本质上,我想要的是解析字符串,以便在它们找到“)”符号时将它们拆分,从而保留字符串的所有符号。

我尝试过使用 strplit() 和一些正则表达式变体,但我一直没能找到诀窍...

有什么帮助吗?

谢谢

如果您想计算字符数,这样做可能更方便:

x <- "...((((.....))))...........(((((((...((..(((..((((...((((((.....)))).))...)))).))).))...)))))))......."


with(rle(strsplit(x, "")[[1]]), setNames(lengths, values))
##  .  (  .  )  .  (  .  (  .  (  .  (  .  (  .  )  .  )  .  )  .  )  .  )  .  )  . 
##  3  4  5  4 11  7  3  2  2  3  2  4  3  6  5  4  1  2  3  4  1  3  1  2  3  7  7 

您可以执行 lookahead 并查找以右括号结尾的点,这些点紧跟在左括号之后。

x <- c("....(((..((((((((.(((((((((((..))))))))))).))))))))..)))..", 
       "...((((.....))))...........(((((((...((..(((..((((...((((((.....)))).))...)))).))).))...))))))).......")
strsplit(x, "\((?=(\.+\)))", perl = TRUE)
# [[1]]
# [1] "....(((..((((((((.(((((((((("  "..))))))))))).))))))))..))).."
# 
# [[2]]
# [1] "...((("  ".....))))...........(((((((...((..(((..((((...((((("
# [3] ".....)))).))...)))).))).))...)))))))......."

您可以使用 DavidArenburg 的 逻辑获得您指定的输出,但有一点不同 - David 使用 lookahead 正则表达式找到模式 .{N}) 之前的 (,其中 N 可以是任何数字。 variable-length 后视(其中模式包含未指定的 a 字符)是理想的,但不起作用(读取 - 不允许)。诀窍是 反转字符串 以使用 variable-length 前瞻,就像 variable-length 后视操作一样。

数据

S <- c("....(((..((((((((.(((((((((((.........))))))))))).))))))))..)))..", "...((((.....))))...........(((((((...((..(((..((((...((((((.....)))).))...)))).))).))...))))))).......")

函数

reverse_string <- function(S) {
    paste(rev(unlist(strsplit(S, ""))), collapse="")
}

myfun <- function(S) {
    T <- reverse_string(S)
    result <- unlist(strsplit(T, "\)(?=(\.+\())", perl = TRUE))
    setNames(rev(sapply(result, function(i) reverse_string(i))), NULL)
}

结果

lapply(S, myfun)

# [[1]]
# [1] "....(((..((((((((.(((((((((((........."
# [2] ")))))))))).))))))))..))).."            

# [[2]]
# [1] "...((((....."                                       
# [2] ")))...........(((((((...((..(((..((((...((((((....."
# [3] "))).))...)))).))).))...)))))))......."