Как изменить столбец на список значений на основе разделителя - PullRequest
0 голосов
/ 06 декабря 2018

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

SampleID    Chrom   Start       End         ID
HSB275      chr1    243216377   243219494   ENST00000366542|ENSG00000143702|protein_coding|protein_coding,chr1,243216377,243219494;ENST00000366543|ENSG00000143702|protein_coding|protein_coding,chr1,243216377,243219494
HSB274      chr10   952208      979839      ENST00000381466|ENSG00000205740|antisense|processed_transcript,chr10,971146,979839
HSB272      chr10   1046378     1047984     ENST00000381344|ENSG00000067064|protein_coding|protein_coding,chr10,1046378,1047984;ENST00000491735|ENSG00000067064|processed_transcript|protein_coding,chr10,1046378,1047984;ENST00000427898|ENSG00000067064|protein_coding|protein_coding,chr10,1046378,1047984
HSB481      chr11   654157      655184      ENST00000527170|ENSG00000177030|nonsense_mediated_decay|protein_coding,chr11,654157,655184

Что я хочу сделать, это уменьшить столбец ID до просто списка значений «ENSGXXXXXXX», которые разделены символом «,"если в строке есть несколько значений, чтобы они выглядели как столбец Genes ниже:

Желаемый результат:

SampleID    Chrom   Start       End         Genes
HSB275      chr1    243216377   243219494   ENSG00000143702,ENSG00000143702
HSB274      chr10   952208      979839      ENSG00000205740
HSB272      chr10   1046378     1047984     ENSG00000067064,ENSG00000067064,ENSG00000067064
HSB481      chr11   654157      655184      ENSG00000177030

Ответы [ 5 ]

0 голосов
/ 06 декабря 2018

данные

df <- read.table(text =
    "SampleID    Chrom   Start       End         ID
HSB275      chr1    243216377   243219494   ENST00000366542|ENSG00000143702|protein_coding|protein_coding,chr1,243216377,243219494;ENST00000366543|ENSG00000143702|protein_coding|protein_coding,chr1,243216377,243219494
HSB274      chr10   952208      979839      ENST00000381466|ENSG00000205740|antisense|processed_transcript,chr10,971146,979839
HSB272      chr10   1046378     1047984     ENST00000381344|ENSG00000067064|protein_coding|protein_coding,chr10,1046378,1047984;ENST00000491735|ENSG00000067064|processed_transcript|protein_coding,chr10,1046378,1047984;ENST00000427898|ENSG00000067064|protein_coding|protein_coding,chr10,1046378,1047984
HSB481      chr11   654157      655184      ENST00000527170|ENSG00000177030|nonsense_mediated_decay|protein_coding,chr11,654157,655184", header = T)

мое решение

Я определяю две функции, которые могут пригодиться в будущем и решить эту задачу:

Первый, extract_matches, извлекает все совпадения для каждого элемента в str.vec.Возвращает список всех совпадающих подстрок, соответствующих шаблону.Он переносит gregexpr, который возвращает только информацию о положении для совпадений.

Второй, extract_matches_aggregating, всегда возвращает вектор, поскольку он объединяет все найденные совпадения, используя sep=.Это зависит от extract_matches.

. Эти две функции используются для извлечения всех идентификаторов ENSG и связывания их с помощью ",".

extract_matches <- function(pattern, str.vec) {
  Map(function(m, s) substring(s, m, m + attr(m, "match.length") - 1), gregexpr(pattern, str.vec), str.vec)
}

extract_matches_aggregating <- function(pattern, str.vec, sep = "; ") {
  sapply(extract_matches(pattern, str.vec), function(res_vec) {
           paste(res_vec, collapse = sep)})
}

df$ID <- extract_matches_aggregating(pattern = "ENSG\\d+", str.vec = df$ID, sep = ", ")

df - это:

  SampleID Chrom     Start       End
1   HSB275  chr1 243216377 243219494
2   HSB274 chr10    952208    979839
3   HSB272 chr10   1046378   1047984
4   HSB481 chr11    654157    655184
                                                 ID
1                  ENSG00000143702, ENSG00000143702
2                                   ENSG00000205740
3 ENSG00000067064, ENSG00000067064, ENSG00000067064
4                                   ENSG00000177030

Это решение будет быстрее на больших таблицах, чем любое решение, использующее strsplit и sapply и lapply.

0 голосов
/ 06 декабря 2018

Моя попытка:

genes %>% 
  mutate_at(vars(ID), funs(str_extract_all(., "ENSG[:digit:]*") %>% 
                                     str_replace_all("c|\"|\\(|\\)", "")))

    # A tibble: 4 x 5
  SampleID Chrom     Start       End ID                                               
  <chr>    <chr>     <dbl>     <dbl> <chr>                                            
1 HSB275   chr1  243216377 243219494 ENSG00000143702, ENSG00000143702                 
2 HSB274   chr10    952208    979839 ENSG00000205740                                  
3 HSB272   chr10   1046378   1047984 ENSG00000067064, ENSG00000067064, ENSG00000067064
4 HSB481   chr11    654157    655184 ENSG00000177030   

Это находит любое совпадение с шаблоном с ENSG<any length of numeric characters>, затем приводит список к вектору соответствующих строк символов и приводит в порядок все нежелательные символы.

Хотялично в духе аккуратных данных я бы помещал каждый «идентификатор» в отдельный столбец, копируя соответствующие данные SampleID / Chrom / Start / End.

0 голосов
/ 06 декабря 2018

Вот вариант tidyverse

library(tidyverse)
df %>%
    mutate(Genes = map_chr(str_split(ID, ";"), ~toString(map(str_split(.x, "\\|"), 2)))) %>%
    select(-ID)
#  SampleID Chrom     Start       End
#1   HSB275  chr1 243216377 243219494
#2   HSB274 chr10    952208    979839
#3   HSB272 chr10   1046378   1047984
#4   HSB481 chr11    654157    655184
#                                              Genes
#1                  ENSG00000143702, ENSG00000143702
#2                                   ENSG00000205740
#3 ENSG00000067064, ENSG00000067064, ENSG00000067064
#4                                   ENSG00000177030

Пример данных

df <- read.table(text =
    "SampleID    Chrom   Start       End         ID
HSB275      chr1    243216377   243219494   ENST00000366542|ENSG00000143702|protein_coding|protein_coding,chr1,243216377,243219494;ENST00000366543|ENSG00000143702|protein_coding|protein_coding,chr1,243216377,243219494
HSB274      chr10   952208      979839      ENST00000381466|ENSG00000205740|antisense|processed_transcript,chr10,971146,979839
HSB272      chr10   1046378     1047984     ENST00000381344|ENSG00000067064|protein_coding|protein_coding,chr10,1046378,1047984;ENST00000491735|ENSG00000067064|processed_transcript|protein_coding,chr10,1046378,1047984;ENST00000427898|ENSG00000067064|protein_coding|protein_coding,chr10,1046378,1047984
HSB481      chr11   654157      655184      ENST00000527170|ENSG00000177030|nonsense_mediated_decay|protein_coding,chr11,654157,655184", header = T)
0 голосов
/ 06 декабря 2018
library(dplyr)
library(stringr) #str_extract_all
df %>% group_by(SampleID) %>% #Use rowwise() if you do not like group_by
       mutate(Genes = paste(str_extract_all(ID, 'ENSG\\d+',simplify = T),collapse = ',')) %>% 
       select(-ID)

# A tibble: 4 x 5
# Groups:   SampleID [4]
SampleID Chrom     Start       End Genes                                          
<fct>    <fct>     <int>     <int> <chr>                                          
1 HSB275   chr1  243216377 243219494 ENSG00000143702,ENSG00000143702                
2 HSB274   chr10    952208    979839 ENSG00000205740                                
3 HSB272   chr10   1046378   1047984 ENSG00000067064,ENSG00000067064,ENSG00000067064
4 HSB481   chr11    654157    655184 ENSG00000177030  
0 голосов
/ 06 декабря 2018

У вас нет фиксированного разделителя, но с помощью strpslit мы можем разделить столбец ID на различные разделители (,, ;, |), тогда для каждого элемента сохраните только те значения, которые начинаютсяс "ENSG" и удалите другие.

sapply(strsplit(df$ID, ",|\\||;"), 
          function(x) toString(grep("^ENSG", x, value = TRUE)))


#[1] "ENSG00000143702, ENSG00000143702"                 
#[2] "ENSG00000205740"                                  
#[3] "ENSG00000067064, ENSG00000067064, ENSG00000067064"
#[4] "ENSG00000177030"      
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...