计算R

时间:2015-06-19 18:59:31

标签: regex r string substring stringr

我正在使用R,我有一个包含4个独特字母(DNA)字符串的数据框。我有兴趣计算这些字符串中出现的某些独特字母组合的时间。其中一种可能的情况是检测我多次看到相同的字母背靠背。

我已经遇到过几种可能的方法来实现这一点,使用正则表达式和像stringr这样的包,但仍有一个问题。

这些方法似乎不会遍历子字符串(逐个字母)并考虑行中的下一个字母作为遵守。这是一个问题,同一个字母的重复次数超过2次。

示例(我想计算时间“CC”,而true_count列是我想要的输出):

sequence  stringr_count  true_count
ACCTACGT      1             1
CCCCCCCC      4             7
ACCCGCCT      2             3

1 个答案:

答案 0 :(得分:4)

我建议使用stringi::stri_count_fixed,如下所示:

> library(stringi)
> seqs <- data.frame(sequence=c('ACCTACGT', 'CCCCCCCC', 'ACCCGCCT'))
> opts <- stri_opts_fixed(overlap=TRUE)
> seqs$true_count <- stri_count_fixed(str=seqs$sequence, pattern='CC', opts_fixed=opts)
> seqs
  sequence true_count
1 ACCTACGT          1
2 CCCCCCCC          7
3 ACCCGCCT          3

使用固定模式stringi比使用gregexpr快一个数量级:

library(microbenchmark)

# Answer provided by @user20650 in the comments
f1 <- function(x) sapply(gregexpr('(?=CC)', x, perl=T) , function(i) sum(i>0))

f2 <- function(x) stri_count_fixed(
    str=x, pattern='CC',
    opts_fixed=stri_opts_fixed(overlap=TRUE))

# Generate random sequences
sequence <- stri_rand_strings(n=10000, length=1000, pattern='[ATGC]')

Microbenchmark结果:

> microbenchmark(f1(sequence), f2(sequence))
Unit: milliseconds
         expr       min        lq      mean    median       uq       max neval
 f1(sequence) 290.90393 304.87107 329.11392 313.39819 327.9860 437.10229   100
 f2(sequence)  20.99733  21.12559  21.39206  21.26017  21.4377  27.68867   100

您还可以查看Biostrings library。根据我的经验,它通常比使用stringi慢,并且需要一些额外的步骤,但提供了许多用于处理生物序列的有用功能,包括countPattern

library(Biostrings)

bsequence <- DNAStringSet(sequence)
f3 <- function(x) vcountPattern('CC', x)

Microbenchmark结果:

> microbenchmark(f2(sequence), f3(bsequence))
Unit: milliseconds
          expr      min       lq     mean   median       uq      max neval
  f2(sequence) 20.83336 21.11473 21.36759 21.25088 21.45000 23.80708   100
 f3(bsequence) 86.95430 89.10023 89.51665 89.37103 89.87699 91.88203   100

只是为了确定:

> identical(f1(seqs$sequence), f2(seqs$sequence),  f3(BStringSet(seqs$sequence))
[1] TRUE