Есть ли способ сгруппировать несколько групп строк по сходству? - PullRequest
1 голос
/ 07 мая 2019

У меня есть данные секвенирования следующего поколения для нескольких пациентов (Пациент1, Пациент2, Пациент3 ...).

Образцы пациентов могут быть от одного заболевания или разных заболеваний.Мы знаем, что частота определенных мутаций выше при определенных заболеваниях, некоторые варианты являются причиной болезни, другие связаны с болезнью, и мы не знаем, как они способствуют болезни и т.д. Я ищу способ кластеризацииэти пациенты на основе измененных генов, чтобы увидеть, есть ли какие-либо общие черты ... Один ген может иметь несколько изменений (например, NRAS G12D против NRAS G13D против NRAS Q61K ...).Порядок измененных генов у данного пациента не должен иметь значения.Типичный результат у одного пациента - около 500 изменений, а количество пациентов - около ста.

Я проверял предыдущие посты, вопрос был о кластеризации строк, составляющих один список, это скорее между несколькими списками строк, а.

Спасибо за вашу помощь.

Данные для одного пациента выглядят так:

    #Patient1
    chromosome <- c("X",    "7",    "10",   "1",    "X",    "5",    "5",    "X",    "10",   "7")
    position <- c("70360589","128829066","89692923","11206853","70360680","176637576","176637471","70360648","89692913","148543694")
    reference <- c("AGC","A","G","AC","GCA","T","G","CAG","G","AA")
    alter <- c("","G","A","","","C","A","","A","")
    gene <- c("MED12","SMO","PTEN","MTOR","MED12","NSD1","NSD1","MED12","PTEN","EZH2")
    cdot <- c("c.6165_6167delGCA","c.74A>G","c.407G>A","c.4571-6_4571-5delGT","c.6256_6258delCAG","c.2176T>C","c.2071G>A","c.6226_6228delCAG","c.397G>A","c.118-5_118-4delTT")
    pdot <- c("Q2076del","D25G","C136Y"," ","Q2086del","S726P","A691T","Q2076del","V133I"," ")
    patient1 <- data.frame(chromosome, position, reference, alter, gene, cdot, pdot)

Мутация может быть представлена ​​по-разному, ген с cdot,ген с gdot, хромосома с ref и alter и т. д. Самый удобный для меня - это ген & pdot, так как он более информативен, так как сообщает мне измененный ген и то, что такое atleration (например, PTEN - это ген, C25G означает, что эталонный аминокислота «C» в положении 25 заменяется аминокислотой «G»).

Я попытался объединить каждую пару Gene & pdot в одну строку, поэтому, если у пациента 10 изменений, как в приведенном выше кадре данных,У меня будет 10 строк.Я сделал бы это для всех пациентов, чем кластеризовал бы всех пациентов, основываясь на их изменениях.Мой вопрос заключается в том, каков наилучший подход для кластеризации нескольких пациентов в этом примере.

Еще два пациента:

    #Patient2
    chromosome <- c("X","6","1","1","6","12","5","X","1","10")
    position <- c("47424495","157100024","78429978","242023898","30858801","49427266","176637576","70360648","78435702","89692913")
    reference <- c("A","GGA","T","A","C","TGC","T","CAG","AA","G")
    alter <- c("","","","G","","","C","","","A")
    gene <- c("ARAF","ARID1B","FUBP1","EXO1","DDR1","KMT2D","NSD1","MED12","FUBP1","PTEN")
    cdot <- c("c.416delA","c.983_985delGAG","c.901delA","c.836A>G","c.474delC","c.11220_11222delGCA","c.2176T>C","c.6226_6228delCAG","c.121-4_121-3delTT","c.397G>A")
    pdot <- c("K139fs","G328del","I301fs","N279S","M159fs","Q3745del","S726P","Q2076del","","V133I")
    patient2 <- data.frame(chromosome, position,  reference, alter, gene, cdot, pdot)


    #Patient3
    chromosome <- c("1","2","11","14","14","12","2","19","12","17","X","1","10")
    position <- c("120539781","141259448","64572018","35871217","102551161","49426952","29416366","18273047","49426730","29490295","70360648","78435702","89692913")
    reference <- c("G","A","T","G","TCT","C","G","T","GCT","G","CAG","AA","G")
    alter <- c("A","","C","A","","T","C","C","","A","","","A")
    gene <- c("NOTCH2","LRP1B","MEN1","NFKBIA","HSP90AA1","KMT2D","ALK","PIK3R2","KMT2D","NF1","MED12","FUBP1","PTEN")
    cdot <- c("c.590C>T","c.8663-5delT","c.1621A>G","c.*2C>T","c.1202_1204delAGA","c.11536G>A","c.4587C>G","c.937T>C","c.11756_11758delAGC","c.380G>A","c.6226_6228delCAG","c.121-4_121-3delTT","c.397G>A")
    pdot <- c("T197I","","T541A","","K401del","G3846S","D1529E","S313P","Q3919del","G127E","Q2076del","","V133I")
    patient3 <- data.frame(chromosome, position,  reference, alter, gene, cdot, pdot)

Чтобы упростить ситуацию, я составил этот пример:

    #Simple Example
    modules1 <- c("maths", "physics", "geometry", "languages", "science", "geology")
    scores1 <- c("A+", "A", "A", "B+", "B", "B")
    student1 <- data.frame(modules1, scores1)
    modules2 <- c("music", "dance", "languages", "science")
    scores2 <- c("A+", "A+", "A+", "B")
    student2 <- data.frame(modules2, scores2)
    modules3 <- c("languages", "science", "physics", "maths")
    scores3 <- c("A+", "A+", "A+", "A")
    student3 <- data.frame(modules3, scores3)

Как я могу объединить учащихся 1, 2 и 3 на основе их оценок.Я ожидаю, что у меня будет дендрограмма с учениками 1 и 3 ближе друг к другу, чем студент 2.

1 Ответ

0 голосов
/ 10 мая 2019

Я думаю, вам нужно stringdist(). Пакет strndist предлагает «Приблизительное сопоставление строк и функции расстояния между строками». Он предлагает множество алгоритмов, но в этом примере я использую расстояние Яро – Винклера (Winkler, 1990), которое является мерой сходства между двумя строками. Чем выше расстояние Джаро-Винклера для двух струн, тем больше сходства струн. Метрика расстояния Джаро-Винклера разработана и лучше всего подходит для коротких строк, таких как личные имена. Оценка нормализуется таким образом, что 0 означает отсутствие сходства, а 1 - точное совпадение.

Данные 100 пациентов могут быть объединены в один кадр данных. Заимствуя из приведенного выше кода, я расширяю его как;

## Lets merge all data frames into one
df.1<- merge(patient1, patient2 , all = TRUE)
df.master <- merge(df.1, patient3 , all = TRUE)
# replace missing entries with 0
df.master[is.na(df.master)] <- 0
head(df.master, 5)
  chromosome  position reference alter   gene                 cdot   pdot
1          1  11206853        AC         MTOR c.4571-6_4571-5delGT       
2          1 242023898         A     G   EXO1             c.836A>G  N279S
3          1  78429978         T        FUBP1            c.901delA I301fs
4          1  78435702        AA        FUBP1   c.121-4_121-3delTT       
5          1 120539781         G     A NOTCH2             c.590C>T  T197I

Теперь давайте измерим расстояние между строками. Так как вы упомянули, что интерес к переменной gene и pdot. Поэтому я использую их следующим образом:

library(stringdist)

# find the unique genes
uniquegenes <- unique(as.character(df.master$pdot))
# determine the distance between various string using the Jar-Winkler distance
distancemodels <- stringdistmatrix(uniquegenes,uniquegenes,method = "jw")
rownames(distancemodels) <- uniquegenes
# Perform hierarchical clustering
hc <- hclust(as.dist(distancemodels))
# show the plot
plot(hc)

Rplot-SOquestion-00

# look at clusters
dfClust <- data.frame(uniquegenes, cutree(hc, k=4))
names(dfClust) <- c('gene_name','cluster')
print(paste('Average number of genes per cluster:', mean(table(dfClust$cluster))))
[1] "Average number of genes per cluster: 5.75"

# the average number of genes per cluster is 5. Lets look at these genes
t <- table(dfClust$cluster)
t <- cbind(t,t/length(dfClust$cluster))
t <- t[order(t[,2], decreasing=TRUE),]
p <- data.frame(factorName=rownames(t), binCount=t[,1], percentFound=t[,2])
dfClust <- merge(x=dfClust, y=p, by.x = 'cluster', by.y='factorName', all.x=T)
dfClust <- dfClust[rev(order(dfClust$binCount)),]
names(dfClust) <-  c('cluster','gene_name')
head (dfClust[c('cluster','gene_name')],5)
   cluster gene_name
12       1     S313P
11       1    M159fs
10       1     G127E
9        1      D25G
8        1    K139fs

Очевидно, кластер 1 является крупнейшим, удерживающим большинство генов. Надеюсь, это поможет.

...