解析字符串并将其拆分为 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] "))).))...)))).))).))...)))))))......."
我在处理 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] "))).))...)))).))).))...)))))))......."