如何通过字符对齐方式划分R中的 Dataframe ?

lb3vh1jj  于 2023-03-20  发布在  其他
关注(0)|答案(1)|浏览(86)

我有一个数据框,其中的“ID”行包含肽序列。我将这些序列分成许多组,每组大约有2-10行。这些组包含一些几乎完全对齐的肽(字符中最多有4个差异)和其他完全不同的肽。我想将我的数据框进行子集化,并创建一个只有“唯一”值的新数据框:也就是说,只有每组的值彼此不同。如果有很少的比对序列,我希望剩下的那个是最长的(我为“character_number”创建了一列)。我考虑过使用elseif和函数adist(),截断值〈6(少于6个差异--只取max(charcter_count))。但是我不知道如何开始。任何想法都将不胜感激!
| 指标|身份证|说明|字符计数|
| - ------|- ------|- ------|- ------|
| 三个|普拉格齐亚|弗拉德12|十四|
| 四个|奥格普拉格哈斯|弗拉德12|十八|
| 五个| akka 基亚拉阿利加阿夫PG|布拉872|十八|
| 六个|阿喀巴喀喀喀喀喀喀|PLM123|十七|
| 七|阿帕阿帕阿帕阿帕阿帕|巴阿拉|十九|
| 八个|阿帕阿帕阿帕阿帕阿帕|巴阿拉|二十个|
| 九|阿帕阿帕阿帕阿帕阿帕|巴阿拉|二十一|
| 四四三|润滑油 Package |茨瓦奇巴|十六|
| 四四四|插图|茨瓦奇巴|十七|
| 七三六|国家石油公司|茨瓦奇巴|十六|
例如,这里我希望有一个新数据框,其中包含行:4(3基本相同但较短),5,6,9,444,736(这里它们都有相同的描述但序列不同)
使用:adist(all_peptides$id[3],all_peptides$id[4]〉我得到4,它低于所需的截止值,所以我希望它只选择4。然而,adist(all_peptides$id[444],all_peptides$id[736])〉是16,所以我希望两者都包括在新的 Dataframe 中。然而,我不知道如何在更大的范围内实现这一点(比较来自同一组的所有序列等)。

kfgdxczn

kfgdxczn1#

假设Description表示您所称的“组”,您可以使用group_by(Description)在每个组内进行条件筛选。例如:

library(dplyr)
library(purrr)

df <- tribble(
  ~index, ~id,                     ~Description, ~character_count,
  3,      "AAGKGPLATGGIAA",        "vlad12",     14,
  4,      "AAGKGPLATGGIAASGKK",    "vlad12",     18,
  5,      "AAKAQYRAAALLGAAVPG",    "bla872",     18,
  6,      "AAKPKVAKAKKVVVKKK",     "plm123",     17,
  7,      "AAPAPAAAPAPAPAAAPEP",   "bbaala",     19,
  8,      "AAPAPAAAPAPAPAAAPEPE",  "bbaala",     20,
  9,      "AAPAPAAAPAAAPAPAPEPER", "bbaala",     21,
  443,    "ILVRYTQPAPQVSTPT",      "cvacba",     16,
  444,    "ILVRYTQPAPQVSTPTL",     "cvacba",     17,
  736,    "NPSLPPPERPAAEAMC",      "cvacba",     16
)

df %>%
  group_by(Description) %>%
  filter(
    ifelse(
      row_number() == 1 & n() == 1, FALSE, # to not use map if only one id in group
      map_lgl(id, \(x) min(adist(x, id[id != x])) >= 6)
    ) %>%
      ifelse(., ., nchar(id) == max(nchar(id[!.])))
  ) %>%
  ungroup()

# A tibble: 6 × 4
  index id                    Description character_count
  <dbl> <chr>                 <chr>                 <dbl>
1     4 AAGKGPLATGGIAASGKK    vlad12                   18
2     5 AAKAQYRAAALLGAAVPG    bla872                   18
3     6 AAKPKVAKAKKVVVKKK     plm123                   17
4     9 AAPAPAAAPAAAPAPAPEPER bbaala                   21
5   444 ILVRYTQPAPQVSTPTL     cvacba                   17
6   736 NPSLPPPERPAAEAMC      cvacba                   16

filter()保留TRUE的值。这里,map_lgl(id, \(x) min(adist(x, id[id != x])) >= 6)首先为id设置TRUE,这些id与组中的其他id至少有6个字符不同(即,超过您的截止值);然后ifelse(., ., nchar(id) == max(nchar(id[!.])))设置TRUE用于提醒id s(低于截止值的那些),如果它们是最长的一个。注意,这将在一个组中保持相同/重复的id s,因为您没有指定如何处理它。
EDIT:一段稍有不同的代码,首先显式定义一个变量来判断它们是否高于截止值,然后进行过滤,这可能更容易理解:

df %>%
  group_by(Description) %>%
  mutate(
    above_cutoff = ifelse(
      row_number() == 1 & n() == 1, FALSE, # so to not use adist if only one id in group
      map_lgl(id, \(x) min(adist(x, id[id != x])) >= 6)
    )
  ) %>%
  filter(above_cutoff | nchar(id) == max(nchar(id[!above_cutoff]))) %>%
  ungroup()

相关问题