How to remove character strings that are detected/contained within other character strings, but only within a specified group_by()-argument

huangapple go评论67阅读模式
英文:

How to remove character strings that are detected/contained within other character strings, but only within a specified group_by()-argument

问题

以下是您要求的翻译的内容:

让我们假设我有:

    > w
       digest    gene          seq
    1     InS  AB0583          AAB
    2     InS  AB0583        AABKR
    3     InS  AB0583      GFHGHGG
    4     PAC PU83022          EUT
    5     PAC PU83022      HSFSFJF
    6     PAC PU83022        EUTCK
    7     PAC PU83022       EUTCKJ
    8     InS PO93853         HDGJ
    9     InS PO93853        HDGJU
    10    InS PO93853       YTYEYD
    11    InS PO93853 YTYEYDJHSGSG
    12    InS PO93853   SALGHAGGEE

我已经应用了两种不同的方法来识别蛋白质(使用它们的基因名w$gene解码)。这些方法编码在w$digest中。如您所见,w$gene中的每个w$digest内可能存在w$seq的重叠序列,例如EUT也在EUTCK内,而后者又在EUTCKJ内。

我想知道已经识别出了多少个唯一的氨基酸,即w$seq中的每个字母。因此,在grouped_by(digest, gene)时,我需要删除任何被检测到在另一个字符串中的字符字符串,但仅保留具有最多字符的字符字符串。

我在tidyverse中寻求解决方案。

帮助需要:

(1) 计算字符数并按以下方式排列:

    w <- w %>%
      mutate(count = str_count(seq)) %>%
      arrange(digest, gene, count)

因此:

    > w
       digest    gene          seq count
    1     InS  AB0583          AAB     3
    2     InS  AB0583        AABKR     5
    3     InS  AB0583      GFHGHGG     7
    4     InS PO93853         HDGJ     4
    5     InS PO93853        HDGJU     5
    6     InS PO93853       YTYEYD     6

(2) group_by(digest, gene),现在删除在另一个w$seq内被检测到的行(在此分组内),保留具有最多字符的行。

输出

    > w
       digest    gene          seq count
    1     InS  AB0583        AABKR     5 #*
    2     InS  AB0583      GFHGHGG     7
    3     InS PO93853        HDGJU     5 #**
    4     InS PO93853   SALGHAGGEE    10
    5     InS PO93853 YTYEYDJHSGSG    12 #***
    6     PAC PU83022       EUTCKJ     6 #****
    7     PAC PU83022      HSFSFJF     7

因此,预期的输出

    > w
       digest    gene          seq count
    1     InS  AB0583        AABKR     5 
    2     InS  AB0583      GFHGHGG     7
    3     InS PO93853        HDGJU     5 
    4     InS PO93853   SALGHAGGEE    10
    5     InS PO93853 YTYEYDJHSGSG    12 
    6     PAC PU83022       EUTCKJ     6 
    7     PAC PU83022      HSFSFJF     7

数据

    w <- data.frame(
      digest = c(rep("InS", 3), rep("PAC", 4), rep("InS", 5)),
      gene = c(rep("AB0583", 3), rep("PU83022", 4), rep("PO93853", 5)),
      seq = c("AAB", "AABKR", "GFHGHGG",
              "EUT", "HSFSFJF", "EUTCK", "EUTCKJ",
              "HDGJ", "HDGJU", "YTYEYD", "YTYEYDJHSGSG", "SALGHAGGEE")
    )

希望这能帮助您理解问题的解决方案。如果您有任何进一步的问题,请随时提出。

英文:

Let's say I have:

&gt; w
   digest    gene          seq
1     InS  AB0583          AAB
2     InS  AB0583        AABKR
3     InS  AB0583      GFHGHGG
4     PAC PU83022          EUT
5     PAC PU83022      HSFSFJF
6     PAC PU83022        EUTCK
7     PAC PU83022       EUTCKJ
8     InS PO93853         HDGJ
9     InS PO93853        HDGJU
10    InS PO93853       YTYEYD
11    InS PO93853 YTYEYDJHSGSG
12    InS PO93853   SALGHAGGEE

I have applied two different methods to identify proteins (decoded with their gene name, w$gene). The methods are encoded in w$digest. As you can see, there may be overlapping sequences of w$seq within each w$gene within each w$digest - e.g. EUT is also within EUTCK, which is within EUTCKJ.

I want to know how many unique amino acids, each letter in w$seq, were identified. Therefore, I need to remove any/all character string(s) that where detected within another character string, but only when grouped_by(digest, gene). The character string with most characters should be kept.

I seek a solution in tidyverse

Help need:

(1) Count the number of characters, and arrange as follows:

w &lt;- w %&gt;%
  mutate(count = str_count(seq)) %&gt;%
  arrange(digest, gene, count)

So that

&gt; w
   digest    gene          seq count
1     InS  AB0583          AAB     3
2     InS  AB0583        AABKR     5
3     InS  AB0583      GFHGHGG     7
4     InS PO93853         HDGJ     4
5     InS PO93853        HDGJU     5
6     InS PO93853       YTYEYD     6

(2) group_by(digest, gene), and now remove rows that contain a w$seq that is detected within another w$seq (within this grouping), and keep the row where the w$seq has most characters.

Output

&gt; w
   digest    gene          seq count
1     InS  AB0583          AAB     3 #* found within:
2     InS  AB0583        AABKR     5 #*
3     InS  AB0583      GFHGHGG     7
4     InS PO93853         HDGJ     4 #** found within:
5     InS PO93853        HDGJU     5 #**
6     InS PO93853       YTYEYD     6 #***
7     InS PO93853   SALGHAGGEE    10
8     InS PO93853 YTYEYDJHSGSG    12 #***
9     PAC PU83022          EUT     3 #****
10    PAC PU83022        EUTCK     5 #****
11    PAC PU83022       EUTCKJ     6 #****
12    PAC PU83022      HSFSFJF     7

Therefore, Expected output

&gt; w
   digest    gene          seq count
1     InS  AB0583        AABKR     5 
2     InS  AB0583      GFHGHGG     7
3     InS PO93853        HDGJU     5 
4     InS PO93853   SALGHAGGEE    10
5     InS PO93853 YTYEYDJHSGSG    12 
6     PAC PU83022       EUTCKJ     6 
7     PAC PU83022      HSFSFJF     7

Data

w &lt;- data.frame(
  digest = c(rep(&quot;InS&quot;, 3), rep(&quot;PAC&quot;, 4), rep(&quot;InS&quot;, 5)),
  gene = c(rep(&quot;AB0583&quot;, 3), rep(&quot;PU83022&quot;, 4), rep(&quot;PO93853&quot;, 5)),
  seq = c(&quot;AAB&quot;, &quot;AABKR&quot;, &quot;GFHGHGG&quot;,
          &quot;EUT&quot;, &quot;HSFSFJF&quot;, &quot;EUTCK&quot;, &quot;EUTCKJ&quot;,
          &quot;HDGJ&quot;, &quot;HDGJU&quot;, &quot;YTYEYD&quot;, &quot;YTYEYDJHSGSG&quot;, &quot;SALGHAGGEE&quot;)
)

答案1

得分: 3

对于group_by()中的每个组,您可以创建一个新的列表列,其中每一行包含该组的所有seq值。然后,您可以进行逐行操作,计算每个seq值在所有值中出现的次数。保留仅出现一次的值将给您想要的结果。

library(dplyr)
library(stringr)
w <- data.frame(
  digest = c(rep("InS", 3), rep("PAC", 4), rep("InS", 5)),
  gene = c(rep("AB0583", 3), rep("PU83022", 4), rep("PO93853", 5)),
  seq = c("AAB", "AABKR", "GFHGHGG",
          "EUT", "HSFSFJF", "EUTCK", "EUTCKJ",
          "HDGJ", "HDGJU", "YTYEYD", "YTYEYDJHSGSG", "SALGHAGGEE")
)

w <- w %>%
  mutate(count = str_count(seq)) %>%
  arrange(digest, gene, count) 

w %>% group_by(digest, gene) %>%
  mutate(all_vals = list(seq)) %>%
  rowwise() %>%
  mutate(win = sum(grepl(seq, all_vals))) %>%
  filter(win == 1) %>%
  dplyr::select(-c(win, all_vals))

<sup>创建于2023年5月25日,使用reprex v2.0.2</sup>

英文:

For each group in group_by() you could make a new list column where each row contains all the seq values for that group. You could then do a row-wise operation where you count the number of times each value of seq shows up in all the values. Keeping the ones that only show up once will give you the result you want.

library(dplyr)
library(stringr)
w &lt;- data.frame(
  digest = c(rep(&quot;InS&quot;, 3), rep(&quot;PAC&quot;, 4), rep(&quot;InS&quot;, 5)),
  gene = c(rep(&quot;AB0583&quot;, 3), rep(&quot;PU83022&quot;, 4), rep(&quot;PO93853&quot;, 5)),
  seq = c(&quot;AAB&quot;, &quot;AABKR&quot;, &quot;GFHGHGG&quot;,
          &quot;EUT&quot;, &quot;HSFSFJF&quot;, &quot;EUTCK&quot;, &quot;EUTCKJ&quot;,
          &quot;HDGJ&quot;, &quot;HDGJU&quot;, &quot;YTYEYD&quot;, &quot;YTYEYDJHSGSG&quot;, &quot;SALGHAGGEE&quot;)
)

w &lt;- w %&gt;%
  mutate(count = str_count(seq)) %&gt;%
  arrange(digest, gene, count) 

w %&gt;% group_by(digest, gene) %&gt;%
  mutate(all_vals = list(seq)) %&gt;% 
  rowwise() %&gt;% 
  mutate(win = sum(grepl(seq, all_vals))) %&gt;% 
  filter(win == 1) %&gt;% 
  dplyr::select(-c(win, all_vals))
#&gt; # A tibble: 7 &#215; 4
#&gt; # Rowwise:  digest, gene
#&gt;   digest gene    seq          count
#&gt;   &lt;chr&gt;  &lt;chr&gt;   &lt;chr&gt;        &lt;int&gt;
#&gt; 1 InS    AB0583  AABKR            5
#&gt; 2 InS    AB0583  GFHGHGG          7
#&gt; 3 InS    PO93853 HDGJU            5
#&gt; 4 InS    PO93853 SALGHAGGEE      10
#&gt; 5 InS    PO93853 YTYEYDJHSGSG    12
#&gt; 6 PAC    PU83022 EUTCKJ           6
#&gt; 7 PAC    PU83022 HSFSFJF          7

<sup>Created on 2023-05-25 with reprex v2.0.2</sup>

答案2

得分: 1

以下是一个潜在的解决方案:

library(tidyverse)

w <- data.frame(
  digest = c(rep("InS", 3), rep("PAC", 4), rep("InS", 5)),
  gene = c(rep("AB0583", 3), rep("PU83022", 4), rep("PO93853", 5)),
  seq = c("AAB", "AABKR", "GFHGHGG",
          "EUT", "HSFSFJF", "EUTCK", "EUTCKJ",
          "HDGJ", "HDGJU", "YTYEYD", "YTYEYDJHSGSG", "SALGHAGGEE")
)

w %>%
  mutate(count = str_count(seq)) %>%
  arrange(digest, gene, count) %>%
  group_by(digest, gene) %>%
  filter(str_count(paste0(seq, collapse = "_"), seq) == 1)
#> # A tibble: 7 × 4
#> # Groups:   digest, gene [3]
#>   digest gene    seq          count
#>   <chr>  <chr>   <chr>        <int>
#> 1 InS    AB0583  AABKR            5
#> 2 InS    AB0583  GFHGHGG          7
#> 3 InS    PO93853 HDGJU            5
#> 4 InS    PO93853 SALGHAGGEE      10
#> 5 InS    PO93853 YTYEYDJHSGSG    12
#> 6 PAC    PU83022 EUTCKJ           6
#> 7 PAC    PU83022 HSFSFJF          7

Created on 2023-05-25 with reprex v2.0.2

原始答案:

这有点尴尬,但它“有效”:

library(tidyverse)

w <- data.frame(
  digest = c(rep("InS", 3), rep("PAC", 4), rep("InS", 5)),
  gene = c(rep("AB0583", 3), rep("PU83022", 4), rep("PO93853", 5)),
  seq = c("AAB", "AABKR", "GFHGHGG",
          "EUT", "HSFSFJF", "EUTCK", "EUTCKJ",
          "HDGJ", "HDGJU", "YTYEYD", "YTYEYDJHSGSG", "SALGHAGGEE")
)

w %>%
  mutate(count = str_count(seq)) %>%
  arrange(digest, gene, count) %>%
  group_by(digest, gene) %>%
  mutate(strings = paste0(seq, collapse = "|")) %>%
  rowwise() %>%
  mutate(strings = gsub(paste0("\\b", seq, "\\b"), "", strings)) %>%
  filter(!grepl(seq, strings)) %>%
  select(-strings) %>%
  ungroup()
#> # A tibble: 7 × 4
#>   digest gene    seq          count
#>   <chr>  <chr>   <chr>        <int>
#> 1 InS    AB0583  AABKR            5
#> 2 InS    AB0583  GFHGHGG          7
#> 3 InS    PO93853 HDGJU            5
#> 4 InS    PO93853 SALGHAGGEE      10
#> 5 InS    PO93853 YTYEYDJHSGSG    12
#> 6 PAC    PU83022 EUTCKJ           6
#> 7 PAC    PU83022 HSFSFJF          7

Created on 2023-05-25 with reprex v2.0.2

英文:

Edit:

Here is a potential solution:

library(tidyverse)

w &lt;- data.frame(
  digest = c(rep(&quot;InS&quot;, 3), rep(&quot;PAC&quot;, 4), rep(&quot;InS&quot;, 5)),
  gene = c(rep(&quot;AB0583&quot;, 3), rep(&quot;PU83022&quot;, 4), rep(&quot;PO93853&quot;, 5)),
  seq = c(&quot;AAB&quot;, &quot;AABKR&quot;, &quot;GFHGHGG&quot;,
          &quot;EUT&quot;, &quot;HSFSFJF&quot;, &quot;EUTCK&quot;, &quot;EUTCKJ&quot;,
          &quot;HDGJ&quot;, &quot;HDGJU&quot;, &quot;YTYEYD&quot;, &quot;YTYEYDJHSGSG&quot;, &quot;SALGHAGGEE&quot;)
)

w %&gt;%
  mutate(count = str_count(seq)) %&gt;%
  arrange(digest, gene, count) %&gt;%
  group_by(digest, gene) %&gt;%
  filter(str_count(paste0(seq, collapse = &quot;_&quot;), seq) == 1)
#&gt; # A tibble: 7 &#215; 4
#&gt; # Groups:   digest, gene [3]
#&gt;   digest gene    seq          count
#&gt;   &lt;chr&gt;  &lt;chr&gt;   &lt;chr&gt;        &lt;int&gt;
#&gt; 1 InS    AB0583  AABKR            5
#&gt; 2 InS    AB0583  GFHGHGG          7
#&gt; 3 InS    PO93853 HDGJU            5
#&gt; 4 InS    PO93853 SALGHAGGEE      10
#&gt; 5 InS    PO93853 YTYEYDJHSGSG    12
#&gt; 6 PAC    PU83022 EUTCKJ           6
#&gt; 7 PAC    PU83022 HSFSFJF          7

<sup>Created on 2023-05-25 with reprex v2.0.2</sup>


Original answer:

This is a bit awkward, but it 'works':

library(tidyverse)

w &lt;- data.frame(
  digest = c(rep(&quot;InS&quot;, 3), rep(&quot;PAC&quot;, 4), rep(&quot;InS&quot;, 5)),
  gene = c(rep(&quot;AB0583&quot;, 3), rep(&quot;PU83022&quot;, 4), rep(&quot;PO93853&quot;, 5)),
  seq = c(&quot;AAB&quot;, &quot;AABKR&quot;, &quot;GFHGHGG&quot;,
          &quot;EUT&quot;, &quot;HSFSFJF&quot;, &quot;EUTCK&quot;, &quot;EUTCKJ&quot;,
          &quot;HDGJ&quot;, &quot;HDGJU&quot;, &quot;YTYEYD&quot;, &quot;YTYEYDJHSGSG&quot;, &quot;SALGHAGGEE&quot;)
)

w %&gt;%
  mutate(count = str_count(seq)) %&gt;%
  arrange(digest, gene, count) %&gt;%
  group_by(digest, gene) %&gt;%
  mutate(strings = paste0(seq, collapse = &quot;|&quot;)) %&gt;%
  rowwise() %&gt;%
  mutate(strings = gsub(paste0(&quot;\\b&quot;, seq, &quot;\\b&quot;), &quot;&quot;, strings)) %&gt;%
  filter(!grepl(seq, strings)) %&gt;%
  select(-strings) %&gt;%
  ungroup()
#&gt; # A tibble: 7 &#215; 4
#&gt;   digest gene    seq          count
#&gt;   &lt;chr&gt;  &lt;chr&gt;   &lt;chr&gt;        &lt;int&gt;
#&gt; 1 InS    AB0583  AABKR            5
#&gt; 2 InS    AB0583  GFHGHGG          7
#&gt; 3 InS    PO93853 HDGJU            5
#&gt; 4 InS    PO93853 SALGHAGGEE      10
#&gt; 5 InS    PO93853 YTYEYDJHSGSG    12
#&gt; 6 PAC    PU83022 EUTCKJ           6
#&gt; 7 PAC    PU83022 HSFSFJF          7

<sup>Created on 2023-05-25 with reprex v2.0.2</sup>

答案3

得分: 1

Using base:

# 添加计数并排序
w$count &lt;- nchar(w$seq)
w &lt;- w[ with(w, order(digest, gene, count)), ]

# 子集
w[ sapply(Map(grepl, w$seq, ave(w$seq, w[ 1:2 ], FUN = list)), sum) == 1, ]
#    digest    gene          seq count
# 2     InS  AB0583        AABKR     5
# 3     InS  AB0583      GFHGHGG     7
# 9     InS PO93853        HDGJU     5
# 12    InS PO93853   SALGHAGGEE    10
# 11    InS PO93853 YTYEYDJHSGSG    12
# 7     PAC PU83022       EUTCKJ     6
# 5     PAC PU83022      HSFSFJF     7
英文:

Using base:

# add count and sort
w$count &lt;- nchar(w$seq)
w &lt;- w[ with(w, order(digest, gene, count)), ]

# subset
w[ sapply(Map(grepl, w$seq, ave(w$seq, w[ 1:2 ], FUN = list)), sum) == 1, ]
#    digest    gene          seq count
# 2     InS  AB0583        AABKR     5
# 3     InS  AB0583      GFHGHGG     7
# 9     InS PO93853        HDGJU     5
# 12    InS PO93853   SALGHAGGEE    10
# 11    InS PO93853 YTYEYDJHSGSG    12
# 7     PAC PU83022       EUTCKJ     6
# 5     PAC PU83022      HSFSFJF     7

huangapple
  • 本文由 发表于 2023年5月25日 17:34:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/76330831.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定