【问题标题】:working my way through a string, in R, by letter position通过字母位置在R中的字符串中工作
【发布时间】:2015-10-17 00:34:05
【问题描述】:

我正在为一门课处理 DNA 序列。更一般地说,我发现自己正在查看超大的字母串,没有逗号或空格,也没有任何将它们分解的信号。

我不确定如何导入它们。

但是当我这样做时,我不知道如何按字母位置在 R 中的字符串中工作。

如果我想要第一个或最后一个 k 字母,这很容易。

但是如果我想从一个长字符串中分离出每组五个连续的字母呢?

可能已经有一个功能了。关于我需要在包库中查找的内容有什么建议吗?

【问题讨论】:

  • 要提取重叠的连续字母吗?
  • 是的,前五个字母和后五个字母共有 4 个字母。

标签: r string parsing


【解决方案1】:

你可以沿着长度迭代,边做边创建子字符串

str <- paste(letters, collapse = "")
sapply(seq(nchar(str)-5), function(i) substr(str, i, i+4))
#  [1] "abcde" "bcdef" "cdefg" "defgh" "efghi" "fghij" "ghijk" "hijkl" "ijklm"
# [10] "jklmn" "klmno" "lmnop" "mnopq" "nopqr" "opqrs" "pqrst" "qrstu" "rstuv"
# [19] "stuvw" "tuvwx" "uvwxy"

而且,使用stringi 这对于大字符串来说要快得多

library(stringi)
inds <- matrix(c(seq(nchar(str)-5), seq(nchar(str)-5)+4), ncol=2)  # indices of substrings
stri_sub(str, inds)

【讨论】:

  • 谢谢。我知道是否必须是一个非常基本的问题。我只是不知道正确的 camand 并且没有通过 R Studio 中的帮助来解决它。
【解决方案2】:

@MrFlick 有一段非常酷的代码可以处理这样的事情。如果你想要 5 个块

x <- 'ACCACCACCCC'
m <- gregexpr('(?=(.{5}))', x, perl = TRUE)
regcapturedmatches(x, m)[[1]]

#         [,1]    [,2]    [,3]    [,4]    [,5]    [,6]    [,7]   
# [1,] "ACCAC" "CCACC" "CACCA" "ACCAC" "CCACC" "CACCC" "ACCCC"

或者寻找特定的模式

m <- gregexpr('(ACC[CA])', x, perl = TRUE)
regcapturedmatches(x, m)[[1]]

#        [,1]   [,2]  
# [1,] "ACCA" "ACCC"

函数(source):

regcapturedmatches<-function(x,m) {

  if (length(x) != length(m))
    stop(gettextf("%s and %s must have the same length",
                  sQuote("x"), sQuote("m")), domain = NA)

  ili <- is.list(m)
  useBytes <- if (ili)
    any(unlist(lapply(m, attr, "useBytes")))
  else 
    any(attr(m, "useBytes"))
  if (useBytes) {
    asc <- iconv(x, "latin1", "ASCII")
    ind <- is.na(asc) | (asc != x)
    if (any(ind))
      Encoding(x[ind]) <- "bytes"
  }
  if (ili) {
    if (any(sapply(m, function(x) {is.null(attr(x,"capture.start"))})==T)) {
      stop("No capture data found (did you use perl=T?)")
    }
    starts<-lapply(m, function(x) {attr(x, "capture.start")})
    lengths<-lapply(m, function(x) {attr(x, "capture.length")})
  } else {
    if (is.null(attr(m,"capture.start"))) {
      stop("No capture data found (did you use perl=T?)")
    }
    starts<-data.frame(t(attr(m, "capture.start")))
    lengths<-data.frame(t(attr(m, "capture.length")))
  }

  Substring<-function(x,starts,lens) {
    if(all(starts<0)) {
      return(character())
    } else {
      return(t(
        mapply(function(x,st,ln) substring(x,st,st+ln-1), 
               x, data.frame(t(starts)), data.frame(t(lens)),
               USE.NAMES=F)
      ))
    }
  }

  y<-Map(
    function(x, sos, mls) {
      Substring(x,sos,mls)
    },
    x,
    starts,
    lengths,
    USE.NAMES = FALSE
  )
  y
}

【讨论】:

    【解决方案3】:

    BioconductorBiostrings 包设计用于处理 DNA 序列。

    library(Biostrings)
    dna = DNAString(paste(sample(c("A", "C", "G", "T"), 10000, TRUE), collapse=""))
    Views(dna, seq_len(nchar(dna) - 5), width=5)
    

    导致

    > Views(dna, seq_len(nchar(dna) - 5), width=5)
      Views on a 10000-letter DNAString subject
    subject: CAGTAGGGCAATTGCTGTCGAATCATCAGTCGGG...CCAACTATAAACAAAAATTAGAAACCACCAGCGA
    views:
           start  end width
       [1]     1    5     5 [CAGTA]
       [2]     2    6     5 [AGTAG]
       [3]     3    7     5 [GTAGG]
       [4]     4    8     5 [TAGGG]
       [5]     5    9     5 [AGGGC]
       ...   ...  ...   ... ...
    [9991]  9991 9995     5 [CCACC]
    [9992]  9992 9996     5 [CACCA]
    [9993]  9993 9997     5 [ACCAG]
    [9994]  9994 9998     5 [CCAGC]
    [9995]  9995 9999     5 [CAGCG]
    

    您可以使用 as.character() 来获得一个普通的旧字符向量,或者继续在 Biostrings 中使用这些。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-09-28
      • 2021-03-30
      • 2012-08-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多