在 R 中的字符串的特定位置查找不同模式的函数

Function to look for different patterns in specific positions in a string in R

我想在 R 中创建一个函数,在字符串中搜索特定位置的特定模式,如果字母出现在既定位置,我想计算它。

数据集示例:

library(dplyr)

mutations <- tibble(
  "position" = c(9,10),
  "AA" = c("G","G"))

strings <- c("EVQLVESGGGLAKPG", 
             "VQLVESGGGLAKPGGS",
             "EVQLVESGGALAKPGGSLRLSCAAS")

所以,在这种情况下,我要寻找位置910,如果有一个字母"G"我想数一下

预期的数据帧或 tibble 输出:

| string | mut_counts |
|________|____________|
|   1    |     2      |
|________|____________|
|   2    |     1      |
|________|____________|
|   3    |     1      |
|________|____________|

在这个例子中,所有的字符串在第9位都有一个"G",所以它们都会得到1,三个序列中只有一个在第10位有一个"G",所以这个序列将有 2.


我正在尝试使用 stringr 包中的 str_locate_all() 来定位位置,然后与我的数据框进行比较以进行计数,但我没有得到我想要的。

library(stringr)

.class_mutations <- function(sequences, mutations){
  .count_pattern <- function(x){
    df <- sum(as.integer(locating_all_patterns[[x]][,"start"] == mutations$position[mut]))
  }
  
  for(mut in nrow(mutations)){
    locating_all_patterns <- str_locate_all(pattern = mutations$AA[mut], sequences)
    counting_patterns <- lapply(locating_all_patterns, .count_pattern)
  }
    
  return(counting_patterns)
}

.class_mutations(strings, mutations)

我收到此错误 Error in locating_all_patterns[[x]] : no such index at level 1,此外,如果您有 better/faster 方法来执行此操作,我也将不胜感激。 我必须考虑到这将应用于数千个字符串,所以我应该避免慢速函数。

谢谢

基础 R

rowSums(outer(strings, seq_len(nrow(mutations)),
        function(st, i) {
          substr(st, mutations$position[i], mutations$position[i]) == mutations$AA[i]
        }))
# [1] 2 1 1

演练:

  • outer 实际上只产生两个向量,两个参数的笛卡尔积的展开。如果我们插入一个 browser() 作为内部 anon-func 的第一行,我们会看到

    data.frame(st, i)
    #                          st i
    # 1           EVQLVESGGGLAKPG 1
    # 2          VQLVESGGGLAKPGGS 1
    # 3 EVQLVESGGALAKPGGSLRLSCAAS 1
    # 4           EVQLVESGGGLAKPG 2
    # 5          VQLVESGGGLAKPGGS 2
    # 6 EVQLVESGGALAKPGGSLRLSCAAS 2
    

    (仅显示为柱状显示的框架。sti 均为简单向量。)

    从这里,知道 substr 跨所有参数向量化,然后对 substr 的单个调用将在每个 st 中找到第 i 个字符戒指。

  • substr 的结果是字母向量。从上面继续相同的 browser() 会话,

    substr(st, mutations$position[i], mutations$position[i])
    # [1] "G" "G" "G" "G" "L" "A"
    mutations$AA[i]
    # [1] "G" "G" "G" "G" "G" "G"
    substr(st, mutations$position[i], mutations$position[i]) == mutations$AA[i]
    # [1]  TRUE  TRUE  TRUE  TRUE FALSE FALSE
    

    mutations$AA[i] 向我们展示了我们正在寻找的东西。这里的矢量化方法的一个好处是 mutations$AA[i] 将始终具有相同的长度,并且按照 substr(.).

    检索到的字母的预期顺序
  • outer本身returns一个matrix,有length(X)行和length(Y)列(XY 分别是 outer 的第一个和第二个参数。

    outer(strings, seq_len(nrow(mutations)),
            function(st, i) {
              substr(st, mutations$position[i], mutations$position[i]) == mutations$AA[i]
            })
    #      [,1]  [,2]
    # [1,] TRUE  TRUE
    # [2,] TRUE FALSE
    # [3,] TRUE FALSE
    

    在每个字符串中找到的正确突变数只是每行的总和。 (因此 rowSums。)


如果您担心大量 mutationsstrings,您可以替换 outer 并遍历 mutations 的每一行:

rowSums(sapply(seq_len(nrow(mutations)), function(i) substr(strings, mutations$position[i], mutations$position[i]) == mutations$AA[i]))
# [1] 2 1 1

这会为每个 mutations 行调用一次 substr,因此如果 outer-explosion 太多,这可能会减少内存占用。

对于基本的 R 选项,我们可以确定字符串函数。这种做法是比较替换目标字符前后每个子串的长度:

nchar(substr(strings, 9, 10)) -
nchar(gsub("G", "", substr(strings, 9, 10), fixed=TRUE))

[1] 2 1 1

数据:

strings <- c("EVQLVESGGGLAKPG", 
             "VQLVESGGGLAKPGGS",
             "EVQLVESGGALAKPGGSLRLSCAAS")