R語言-制作motif的PWM

一褪子、PWM與PFM的介紹

motif指的是轉(zhuǎn)錄因子偏好結(jié)合的DNA序列模式或RNA結(jié)合蛋白偏好結(jié)合的序列模式辙售,一般使用PWM來表示motif。

制作PWM的過程如下:

  1. 首先計算所有序列每個位置的堿基頻數(shù)飞涂,可以得到PFM(Position Frequency Matrix)旦部,這個可以作為ggseqlogo包的輸入來繪制motif圖。
  2. 通過PFM可以進(jìn)一步計算得到PPM(Position Probability Matrix)较店,表示位置頻率矩陣士八,是計算了每個位置四種堿基的出現(xiàn)頻率后得到的矩陣,這個PPM矩陣可以作為TOMTOM的輸入去與其他motif數(shù)據(jù)庫比對梁呈。
  3. 將PPM中的頻率除以堿基背景頻率然后取對數(shù)(log2)以后就得到了PWM(Position Weight Matrix)矩陣婚度。

制作PWM的一個示例數(shù)據(jù)可參考我之前寫的博客

下面介紹一下如何使用R語言來計算motif的PFM和PPM官卡,代碼參考了ggseqlogo的源代碼并進(jìn)行了修改與注釋蝗茁。

二、根據(jù)堿基序列手工制作PFM與PPM

要實現(xiàn)的目標(biāo):輸入含有n條相同長度的DNA或RNA序列寻咒,返回可以表征該motif的PFM或PPM哮翘。

1. 主要實現(xiàn)函數(shù)

letterMatrix <- function(input){
  # Ensure kmers are the same length characters(ggseqlogo)
  # 首先要確保輸入的堿基序列的長度都是一致的
  seq.len = sapply(input, nchar) # 計算每條序列的堿基數(shù)目
  num_pos = seq.len[1] # 第一條序列的堿基數(shù)目
  if(! all(seq.len == num_pos)) { # 所有序列的堿基數(shù)目必須一致,不一致則報錯
    stop('Sequences in alignment must have identical lengths')
  }

  # Construct matrix of letters(ggseqlogo)
  # 接下來構(gòu)建一個矩陣毛秘,每個元素是一個堿基
  split = unlist( sapply(input, function(seq){strsplit(seq, '')}) ) # strsplit可以將字符串切割成單個字符

  t( matrix(split, seq.len, length(split)/num_pos) )
}

make_ppm <- function(seqs, ppm=TRUE, seq_type="dna") {
  # seqs: A vector of strings, each string is a DNA or RNA sequence
  # ppm: Whether to return PPM, default is PPM, else return PFM
  # seq_type: Sequence type, can be "dna" of "rna"

  letter_mat = letterMatrix(seqs) # 構(gòu)建堿基矩陣饭寺,每一行是一條序列阻课,每一列是堿基位置

  # Get namespace(ggseqlogo)
  if(seq_type == "dna") {
    namespace = c("A", "T", "G", "C") 
  } else if (seq_type == "rna" ) {
    namespace = c("A", "U", "G", "C") 
  } else {
    stop('Wrong seq_type! Must be one of "dna" and "rna".')
  }

  # Construct PWM(ggseqlogo)
  pfm_mat = apply(letter_mat, 2, function(pos.data){ # apply第二個參數(shù)為2,表示對列進(jìn)行操作
    # Get frequencies (ggseqlogo)
    t = table(pos.data) # 計算該位置四種堿基的頻數(shù)
    # Match to aa(ggseqlogo)
    ind = match(namespace, names(t)) # 
    # Create column(ggseqlogo)
    col = t[ind] # 
    col[is.na(col)] = 0
    names(col) = namespace

    if(ppm) { # 若返回PPM艰匙,則將堿基頻數(shù)除以該列堿基總數(shù)
      col = col / sum(col)      
    }
    col # 函數(shù)返回值col
  })

  num_pos = nchar(seqs[1])
  colnames(pfm_mat) = 1:num_pos
  pfm_mat

}

用法如下:

seqs <- c("CGTAA", "ATTAG", "CTAAG", "ATTAA", "CATAA")
# 計算PPM(TOMTOM的輸入格式)
ppm <- make_ppm(seqs, ppm=TRUE)
ppm
##     1   2   3 4   5
## A 0.4 0.2 0.2 1 0.6
## T 0.0 0.6 0.8 0 0.0
## G 0.0 0.2 0.0 0 0.4
## C 0.6 0.0 0.0 0 0.0
# 計算PFM(ggseqlogo的輸入格式)
pfm <- make_ppm(seqs, ppm=FALSE) # ppm=FALSE則輸出PFM
pfm
##   1 2 3 4 5
## A 2 1 1 5 3
## T 0 3 4 0 0
## G 0 1 0 0 2
## C 3 0 0 0 0

2. 實現(xiàn)效果

ggseqlogo包可以接受一個存儲堿基序列的字符串向量或者PFM來繪制motif logo限煞,下面就依次使用這兩種方法對5條DNA和RNA序列繪制motif logo,以驗證手工計算出的PFM與該包計算的結(jié)果一致员凝。

2.1 制作DNA的motif logo

首先用ggseqlogo畫一下這5條序列的motif logo署驻,如下圖所示

# install.packages('ggseqlogo')
library('ggseqlogo')

seqs <- c("CGTAA", "ATTAG", "CTAAG", "ATTAA", "CATAA")
ggseqlogo(seqs)
## Warning: `guides(<scale> = FALSE)` is deprecated. Please use `guides(<scale> =
## "none")` instead.
image

接下來使用上面自定義的函數(shù)來計算PFM然后繪制motif logo:

seqs <- c("CGTAA", "ATTAG", "CTAAG", "ATTAA", "CATAA")
pfm <- make_ppm(seqs, ppm=FALSE)
pfm
##   1 2 3 4 5
## A 2 1 1 5 3
## T 0 3 4 0 0
## G 0 1 0 0 2
## C 3 0 0 0 0
ggseqlogo(pfm)
## Warning: `guides(<scale> = FALSE)` is deprecated. Please use `guides(<scale> =
## "none")` instead.
image

可以看到畫出來的圖與直接使用ggseqlogo的結(jié)果是一樣的。

該代碼也可以計算出PPM(TOMTOM需要的格式)绊序,如下所示:

seqs <- c("CGTAA", "ATTAG", "CTAAG", "ATTAA", "CATAA")
pfm <- make_ppm(seqs)
pfm
##     1   2   3 4   5
## A 0.4 0.2 0.2 1 0.6
## T 0.0 0.6 0.8 0 0.0
## G 0.0 0.2 0.0 0 0.4
## C 0.6 0.0 0.0 0 0.0

2.2 制作RNA的motif logo

首先用ggseqlogo畫motif logo如下:

# install.packages('ggseqlogo')
library('ggseqlogo')

seqs <- c("CGUAA", "AUUAG", "CUAAG", "AUUAA", "CAUAA")
ggseqlogo(seqs)
## Warning: `guides(<scale> = FALSE)` is deprecated. Please use `guides(<scale> =
## "none")` instead.
image

使用make_ppm函數(shù)計算PFM硕舆,在對RNA進(jìn)行計算時需要指定seq_type="rna",代碼如下:

seqs <- c("CGUAA", "AUUAG", "CUAAG", "AUUAA", "CAUAA")
pfm <- make_ppm(seqs, ppm=FALSE, seq_type='rna')
pfm
##   1 2 3 4 5
## A 2 1 1 5 3
## U 0 3 4 0 0
## G 0 1 0 0 2
## C 3 0 0 0 0
ggseqlogo(pfm)
## Warning: `guides(<scale> = FALSE)` is deprecated. Please use `guides(<scale> =
## "none")` instead.
image

上述logo圖與ggseqlogo畫出來的結(jié)果是一樣的骤公。

三抚官、PFM->PPM->PWM

上面實現(xiàn)了根據(jù)堿基序列制作PFM與PPM,但如果已經(jīng)有了PFM呢阶捆?有了PFM以后就可以依次計算PPM和PWM了凌节,下面寫一下PFM->PPM->PWM的代碼。

  1. PFM->PPM

代碼如下洒试,

pfm2ppm <- function(pfm) {
  ppm <- apply(pfm, 2, function(col) {col / sum(col)} ) # 對
  return(ppm)
}

# 示例
seqs <- c("CGTAA", "ATTAG", "CTAAG", "ATTAA", "CATAA")
pfm <- make_ppm(seqs, ppm=FALSE)
pfm
##   1 2 3 4 5
## A 2 1 1 5 3
## T 0 3 4 0 0
## G 0 1 0 0 2
## C 3 0 0 0 0
ppm_ori <- make_ppm(seqs)
ppm_ori
##     1   2   3 4   5
## A 0.4 0.2 0.2 1 0.6
## T 0.0 0.6 0.8 0 0.0
## G 0.0 0.2 0.0 0 0.4
## C 0.6 0.0 0.0 0 0.0
ppm <- pfm2ppm(pfm)
ppm
##     1   2   3 4   5
## A 0.4 0.2 0.2 1 0.6
## T 0.0 0.6 0.8 0 0.0
## G 0.0 0.2 0.0 0 0.4
## C 0.6 0.0 0.0 0 0.0
ppm_ori == ppm
##      1    2    3    4    5
## A TRUE TRUE TRUE TRUE TRUE
## T TRUE TRUE TRUE TRUE TRUE
## G TRUE TRUE TRUE TRUE TRUE
## C TRUE TRUE TRUE TRUE TRUE
# 兩種方法計算出來的PPM是一致的倍奢。
  1. PPM->PWM

由PPM到PWM需要先將PPM除以每種堿基的背景頻率(一般情況下四種堿基的背景頻率均為0.25),然后取對數(shù)(log2)就得到了PWM垒棋,代碼如下:

ppm2pwm <- function(ppm) {
  pwm <- log2(ppm / 0.25)
  pwm[is.infinite(pwm)] <- 0 # 頻率為0的堿基取對數(shù)以后是負(fù)無窮卒煞,需要將其置為0
  return(pwm)
}

seqs <- c("CGTAA", "ATTAG", "CTAAG", "ATTAA", "CATAA")
ppm <- make_ppm(seqs)
ppm
##     1   2   3 4   5
## A 0.4 0.2 0.2 1 0.6
## T 0.0 0.6 0.8 0 0.0
## G 0.0 0.2 0.0 0 0.4
## C 0.6 0.0 0.0 0 0.0
pwm <- ppm2pwm(ppm)
pwm
##           1          2          3 4         5
## A 0.6780719 -0.3219281 -0.3219281 2 1.2630344
## T 0.0000000  1.2630344  1.6780719 0 0.0000000
## G 0.0000000 -0.3219281  0.0000000 0 0.6780719
## C 1.2630344  0.0000000  0.0000000 0 0.0000000
  1. 直接讀入PFM矩陣并計算PPM,然后使用ggseqlogo畫圖
seqs_text <- '  1 2 3 4 5
A 2 1 1 5 3
T 0 3 4 0 0
G 0 1 0 0 2
C 3 0 0 0 0'
seqs_pfm <- read.table(text=seqs_text)
# 計算PPM
pfm2ppm(seqs_pfm)
##    X1  X2  X3 X4  X5
## A 0.4 0.2 0.2  1 0.6
## T 0.0 0.6 0.8  0 0.0
## G 0.0 0.2 0.0  0 0.4
## C 0.6 0.0 0.0  0 0.0
# 直接繪圖
library(ggseqlogo)
ggseqlogo(as.matrix(seqs_pfm))
## Warning: `guides(<scale> = FALSE)` is deprecated. Please use `guides(<scale> =
## "none")` instead.
image

四叼架、待優(yōu)化

  1. 優(yōu)化代碼畔裕,使其可自動判斷輸入類型是DNA還是RNA,即無需指定seq_type參數(shù)乖订。
  2. 博客文章需要改一下數(shù)字扮饶,順便將代碼放上去。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末乍构,一起剝皮案震驚了整個濱河市甜无,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌哥遮,老刑警劉巖岂丘,帶你破解...
    沈念sama閱讀 217,277評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異昔善,居然都是意外死亡元潘,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評論 3 393
  • 文/潘曉璐 我一進(jìn)店門君仆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來翩概,“玉大人牲距,你說我怎么就攤上這事≡勘樱” “怎么了牍鞠?”我有些...
    開封第一講書人閱讀 163,624評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長评姨。 經(jīng)常有香客問我难述,道長,這世上最難降的妖魔是什么吐句? 我笑而不...
    開封第一講書人閱讀 58,356評論 1 293
  • 正文 為了忘掉前任胁后,我火速辦了婚禮,結(jié)果婚禮上嗦枢,老公的妹妹穿的比我還像新娘攀芯。我一直安慰自己,他們只是感情好文虏,可當(dāng)我...
    茶點故事閱讀 67,402評論 6 392
  • 文/花漫 我一把揭開白布侣诺。 她就那樣靜靜地躺著,像睡著了一般氧秘。 火紅的嫁衣襯著肌膚如雪年鸳。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,292評論 1 301
  • 那天丸相,我揣著相機與錄音搔确,去河邊找鬼。 笑死灭忠,一個胖子當(dāng)著我的面吹牛妥箕,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播更舞,決...
    沈念sama閱讀 40,135評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼坎吻!你這毒婦竟也來了缆蝉?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,992評論 0 275
  • 序言:老撾萬榮一對情侶失蹤瘦真,失蹤者是張志新(化名)和其女友劉穎刊头,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體诸尽,經(jīng)...
    沈念sama閱讀 45,429評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡原杂,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,636評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了您机。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片穿肄。...
    茶點故事閱讀 39,785評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡年局,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出咸产,到底是詐尸還是另有隱情矢否,我是刑警寧澤,帶...
    沈念sama閱讀 35,492評論 5 345
  • 正文 年R本政府宣布脑溢,位于F島的核電站僵朗,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏屑彻。R本人自食惡果不足惜验庙,卻給世界環(huán)境...
    茶點故事閱讀 41,092評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望社牲。 院中可真熱鬧粪薛,春花似錦、人聲如沸膳沽。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽挑社。三九已至陨界,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間痛阻,已是汗流浹背菌瘪。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留阱当,地道東北人俏扩。 一個月前我還...
    沈念sama閱讀 47,891評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像弊添,于是被迫代替她去往敵國和親录淡。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,713評論 2 354

推薦閱讀更多精彩內(nèi)容