Разделить столбец строк на матрицу строк, используя регулярное выражение с именами столбцов на основе части совпадения

avatar
mikemtnbikes
1 июля 2021 в 16:22
47
3
1

Я создаю табличку из описаний генов в файле FASTA кодирующих белок последовательностей. Вот несколько примеров данных, которые я хочу обработать

seqDescriptions<- c( "lcl|NC_003888.3_cds_NP_624362.1_1 [locus_tag=SCO0001 ][db_xref=GeneID:1095448] [protein=hypothetical protein] [protein_id=NP_624362.1] [location=446..1123] [gbkey=CDS]", 
"lcl|NC_003888.3_cds_NP_624363.1_2 [locus_tag=SCO0002] [db_xref=GeneID:1095447] [protein=hypothetical protein] [protein_id=NP_624363.1] [location=1252..3813] [gbkey=CDS]",
"lcl|NC_003888.3_cds_NP_624364.1_3 [locus_tag=SCO0003] [db_xref=GeneID:1095446] [protein=DNA-binding protein] [protein_id=NP_624364.1] [location=3869..6220] [gbkey=CDS]",
"lcl|NC_003888.3_cds_NP_631871.1_4 [locus_tag=SCO0004] [db_xref=GeneID:1095445] [protein=hypothetical protein] [protein_id=NP_631871.1] [location=6226..7173] [gbkey=CDS]")

Я хочу извлечь начальный набор не пробельных символов в один столбец, а затем информацию справа от каждого тега. Определение тегов вручную

tagList <- c("locus_tag", "db_xref", "protein", "protein_id", "location", "gbkey")

Моя цель — получить табличку, которая выглядит так

# A tibble: 4 x 7
name                                  locus_tag    db_xref       protein ...
<chr>                                 <chr>         <chr>        <chr>  ...
"lcl|NC_003888.3_cds_NP_624362.1_1"  "SCO0001"  "GeneID:1095448" "hypothetical protein" ...
"lcl|NC_003888.3_cds_NP_624363.1_2"  "SCO0002"  "GeneID:1095447" "hypothetical protein" ...

Приведенный ниже код работает, но я хотел бы

  1. Посмотрите, как реализовать это tidyr способом.
  2. Назовите столбцы, используя значение tag по мере создания, а не постфактум.
  3. Узнайте о любых биоинформационных инструментах, которые могли бы сделать это более непосредственно, например, без необходимости вручную определять теги.

.

fastaID <- sub("^(\\S+) .*", "\\1", seqDescriptions) 
seqTags <- sub("^\\S+ (.*)", "\\1", seqDescriptions)

dBase <- tibble(fasta_ID=fastaID)
for(tag in tagsUsed){
    tagPattern  <- paste0(".*\\[", tag, "=([^]]+).*")## Don't need to escape ']' with '^'
    dBase <- tibble::add_column(dBase, sub(tagPattern, "\\1", seqTags), .name_repair="unique" )
}

names(dBase) <- c("fasta_ID", tagsUsed)


tibble(tagsUsed))
Источник

Ответы (3)

avatar
stefan
1 июля 2021 в 16:40
1

Используя tidyr::extract мы могли бы сделать:

d <- data.frame(
  seqDescriptions = seqDescriptions
)

tagList <- c("locus_tag", "db_xref", "protein", "protein_id", "location", "gbkey")
regex_tag <- lapply(tagList, function(.x) paste0("\\[", .x, "=(.*)\\]"))
regex_tag <- unlist(regex_tag)  
regex <- paste(c("^(\\S+)?", regex_tag), collapse = "\\s*")

library(tidyr)

d %>% 
  extract(seqDescriptions, into = c("name", tagList), regex)
#>                                name locus_tag        db_xref
#> 1 lcl|NC_003888.3_cds_NP_624362.1_1  SCO0001  GeneID:1095448
#> 2 lcl|NC_003888.3_cds_NP_624363.1_2   SCO0002 GeneID:1095447
#> 3 lcl|NC_003888.3_cds_NP_624364.1_3   SCO0003 GeneID:1095446
#> 4 lcl|NC_003888.3_cds_NP_631871.1_4   SCO0004 GeneID:1095445
#>                protein  protein_id   location gbkey
#> 1 hypothetical protein NP_624362.1  446..1123   CDS
#> 2 hypothetical protein NP_624363.1 1252..3813   CDS
#> 3  DNA-binding protein NP_624364.1 3869..6220   CDS
#> 4 hypothetical protein NP_631871.1 6226..7173   CDS
mikemtnbikes
7 июля 2021 в 16:50
0

Этот подход мне наиболее понятен. Спасибо!

avatar
onyambu
1 июля 2021 в 17:10
0

не используя много регулярных выражений, мы могли бы сделать:

seqDescriptions %>%
  chartr(':=[]', '=:  ', .)%>%
  strsplit(' +')%>%
  map_df(~cbind.data.frame(grp = .x[1],
              grep(':', .x, value = TRUE) %>%
              textConnection() %>%
              read.dcf(fields = tagList)%>%
                chartr('=', ':', .)))

                               grp locus_tag        db_xref      protein  protein_id   location gbkey
1 lcl|NC_003888.3_cds_NP_624362.1_1   SCO0001 GeneID:1095448 hypothetical NP_624362.1  446..1123   CDS
2 lcl|NC_003888.3_cds_NP_624363.1_2   SCO0002 GeneID:1095447 hypothetical NP_624363.1 1252..3813   CDS
3 lcl|NC_003888.3_cds_NP_624364.1_3   SCO0003 GeneID:1095446  DNA-binding NP_624364.1 3869..6220   CDS
4 lcl|NC_003888.3_cds_NP_631871.1_4   SCO0004 GeneID:1095445 hypothetical NP_631871.1 6226..7173   CDS
mikemtnbikes
7 июля 2021 в 16:51
0

Спасибо. Я не знал о map_df, поэтому все еще думаю об этом.

avatar
r2evans
1 июля 2021 в 16:37
1

Вот гибридный подход:

# add "name" for the first column
tagList <- c("name", "locus_tag", "db_xref", "protein", "protein_id", "location", "gbkey")
rough <- strcapture("^([^]]+)\\s*(\\[[^]]+\\])\\s*(\\[[^]]+\\])\\s*(\\[[^]]+\\])\\s*(\\[[^]]+\\])\\s*(\\[[^]]+\\])\\s*(\\[[^]]+\\])",
                    seqDescriptions, proto=setNames(rep("", length(tagList)), tagList))
rough
#                                 name            locus_tag                  db_xref                        protein               protein_id              location       gbkey
# 1 lcl|NC_003888.3_cds_NP_624362.1_1  [locus_tag=SCO0001 ] [db_xref=GeneID:1095448] [protein=hypothetical protein] [protein_id=NP_624362.1]  [location=446..1123] [gbkey=CDS]
# 2 lcl|NC_003888.3_cds_NP_624363.1_2   [locus_tag=SCO0002] [db_xref=GeneID:1095447] [protein=hypothetical protein] [protein_id=NP_624363.1] [location=1252..3813] [gbkey=CDS]
# 3 lcl|NC_003888.3_cds_NP_624364.1_3   [locus_tag=SCO0003] [db_xref=GeneID:1095446]  [protein=DNA-binding protein] [protein_id=NP_624364.1] [location=3869..6220] [gbkey=CDS]
# 4 lcl|NC_003888.3_cds_NP_631871.1_4   [locus_tag=SCO0004] [db_xref=GeneID:1095445] [protein=hypothetical protein] [protein_id=NP_631871.1] [location=6226..7173] [gbkey=CDS]

С этим мы можем очистить его:

library(dplyr)
rough %>%
  mutate(across(-name, ~ trimws(gsub("^[^=]*=|\\]$", "", .))))
#                                 name locus_tag        db_xref              protein  protein_id   location gbkey
# 1 lcl|NC_003888.3_cds_NP_624362.1_1    SCO0001 GeneID:1095448 hypothetical protein NP_624362.1  446..1123   CDS
# 2 lcl|NC_003888.3_cds_NP_624363.1_2    SCO0002 GeneID:1095447 hypothetical protein NP_624363.1 1252..3813   CDS
# 3 lcl|NC_003888.3_cds_NP_624364.1_3    SCO0003 GeneID:1095446  DNA-binding protein NP_624364.1 3869..6220   CDS
# 4 lcl|NC_003888.3_cds_NP_631871.1_4    SCO0004 GeneID:1095445 hypothetical protein NP_631871.1 6226..7173   CDS
mikemtnbikes
7 июля 2021 в 16:51
0

Спасибо, я нахожу команду strcapture() немного ошеломляющей по своей сложности.

r2evans
7 июля 2021 в 17:45
0

На самом деле это просто (\\[[^]]+\\]) (начните с литерала [, затем несколько символов, затем литерал ]), повторяющийся несколько раз с необязательными разделителями \\s*.