Моя первая мысль - использовать strsplit
с использованием чисел / паренов в качестве разделителей:
str(
strsplit(peptide, '[().[:digit:]]+')
)
# List of 4
# $ : chr [1:3] "aaa" "bbb" "ccc"
# $ : chr [1:2] "aaa" "bbbccc"
# $ : chr [1:3] "aaabbb" "ccc" "ddd"
# $ : chr [1:3] "aaabbb" "cc" "ddd"
Пока это выглядит хорошо, так что теперь мы можем перебирать каждый разрыв и захватывать конкатенации до / после,(Пока игнорируйте параметр removeqmark=
, я его сейчас опишу.)
surrounding <- function(vec, k=5, removeqmark=TRUE) {
l <- length(vec)
out <- sapply(seq_len(l-1), function(i) {
bef <- paste(vec[1:i], collapse="")
aft <- paste(vec[(i+1):l], collapse="")
paste0(substr(bef, max(1, nchar(bef)-k+1), nchar(bef)),
substr(aft, 1, min(k, nchar(aft))))
})
if (removeqmark) out <- gsub("\\?", "", out)
out
}
Теперь мы можем перебирать векторы разделенной строки, используя эту функцию:
str(
lapply(strsplit(peptide, '[().[:digit:]]+'), surrounding)
)
# List of 4
# $ : chr [1:2] "aaabbbcc" "aabbbccc"
# $ : chr "aaabbbcc"
# $ : chr [1:2] "aabbbcccdd" "bbcccddd"
# $ : chr [1:2] "aabbbccddd" "bbbccddd"
К сожалению, выпадает треть последнего вектора.Это не удивительно для меня, поскольку окончание на разделителе не обязательно возвращает пустую строку.Таким образом, мы можем добавить что-то к каждой строке IFF, которую мы заканчиваем на разделителе:
( peptide2 <- gsub("([().[:digit:]])$", "\\1?", peptide) )
# [1] "aaa(0.011)bbb(0.989)ccc" "aaa(1)bbbccc" "aaabbb(0.15)ccc(0.85)ddd"
# [4] "aaabbb(0.75)cc(0.24)ddd(0.01)?"
str(
strsplit(peptide2, '[().[:digit:]]+')
)
# List of 4
# $ : chr [1:3] "aaa" "bbb" "ccc"
# $ : chr [1:2] "aaa" "bbbccc"
# $ : chr [1:3] "aaabbb" "ccc" "ddd"
# $ : chr [1:4] "aaabbb" "cc" "ddd" "?"
str(
lapply(strsplit(peptide2, '[().[:digit:]]+'), surrounding)
)
# List of 4
# $ : chr [1:2] "aaabbbcc" "aabbbccc"
# $ : chr "aaabbbcc"
# $ : chr [1:2] "aabbbcccdd" "bbcccddd"
# $ : chr [1:3] "aabbbccddd" "bbbccddd" "ccddd"
, где по умолчанию мы удаляем знак вопроса из результирующего окружения.Чтобы использовать окружающее число, отличное от 5, просто выполните:
lapply(strsplit(peptide2, '[().[:digit:]]+'), surrounding, k=2)
Чтобы объединить это в data.frame, вам нужно проделать дополнительную работу, поскольку у вас есть строки различной длины.
rows <- lapply(strsplit(peptide2, '[().[:digit:]]+'), surrounding)
( maxrows <- max(lengths(rows)) )
# [1] 3
rows <- lapply(rows, function(r) c(r, rep(NA_character_, maxrows - length(r))))
do.call(rbind, rows)
# [,1] [,2] [,3]
# [1,] "aaabbbcc" "aabbbccc" NA
# [2,] "aaabbbcc" NA NA
# [3,] "aabbbcccdd" "bbcccddd" NA
# [4,] "aabbbccddd" "bbbccddd" "ccddd"
(Это генерирует сэндвич matrix
... в as.data.frame
, если вам нужен кадр.)