R语言手动计算Tajima's D 和 Fst

原理和公式参考:

  1. https://www.jianshu.com/p/c7ba1aa543fe
  2. wikipedia: https://en.wikipedia.org/wiki/Tajima%27s_D
  3. https://www.google.com.hk/search?q=pvalue+for+tajima%27s+D&newwindow=1&client=safari&ei=URDsYZy_OZavoATIyJSYAg&ved=0ahUKEwjcq5ngxMX1AhWWF4gKHUgkBSMQ4dUDCA0&uact=5&oq=pvalue+for+tajima%27s+D&gs_lcp=Cgdnd3Mtd2l6EAMyBwgAEEcQsAMyBwgAEEcQsAMyBwgAEEcQsAMyBwgAEEcQsAMyBwgAEEcQsAMyBwgAEEcQsAMyBwgAEEcQsAMyBwgAEEcQsAMyBwgAEEcQsANKBAhBGABKBQhAEgExSgQIRhgAUABYAGCb0QRoAXABeACAAQCIAQCSAQCYAQDIAQnAAQE&sclient=gws-wiz
  4. https://zhuanlan.zhihu.com/p/52064863

1. 加载数据

##### load data
data<-read.table("mydata.genotype",header=T) #### change this
data<-data[data$Chr=="chr18"] #### select car
data1<-data[,4:dim(data)[2]]
看一眼data

2. 设定参数和两两个体的排列组合

nindiv<-dim(data1)[2]
nsnp<-dim(data1)[1]
pos_data<-data[,1:2] #### change this 
pop1_num<-1:9  ###### change this (前9个是population1,后面是population2,
                ######这个只用于计算Fst,对tajima‘s D没有用)
pop2_num<-10:17  ##### change this
between_or_within_pop<-c()
for(i in 1:(nindiv-1)){
    for(k in (i+1):nindiv){
            print(paste0(i," and ",k))
            if((i %in% pop1_num & k %in% pop2_num) | (i %in% pop2_num & k %in% pop1_num)){
                between_or_within_pop<-c(between_or_within_pop,"between")
        }else{between_or_within_pop<-c(between_or_within_pop,"within")}}
}
#### 17个个体,两两组合类型一共136种。
#### 写清楚哪些是群体间的,哪些是群体内的(Fst计算要用)
#### save between pop pairs num and within pop pair num
nbetween<-sum(between_or_within_pop=="between")
nwithin<-sum(between_or_within_pop=="within")

3. 定义计算函数

##### define function
tajima_and_fst<-function(input_data){
    theta_matrix<-matrix(nrow=dim(input_data)[1],ncol=choose(nindiv,2),0)
    for(snp in 1:dim(input_data)[1]){
        array<-input_data[snp,]
        pair_count=0
        for(i in 1:(nindiv-1)){
            for(k in (i+1):nindiv){
                    pair_count=pair_count+1
                    if(array[i][1,1]!=array[k][1,1]){
                        if (array[i][1,1]=="-"|array[k][1,1]=="-"){
                            theta_matrix[snp,pair_count]=NA
                        }else{theta_matrix[snp,pair_count]=1}
                    }
            }
        }
    }
    theta_matrix1<-theta_matrix
    theta_matrix1[is.na(theta_matrix)]=0
    #### theta_pi是考虑到NA值的,使用了总位点数/非gap位点数 作为标准化常数
    nromalized_factor<-dim(theta_matrix1)[1]/apply(!is.na(theta_matrix),2,sum)
    nromalized_factor[nromalized_factor==Inf]<-1
    
    a1<-sum(1/1:(dim(input_data)[1]-1))
    a2<-sum(1/(1:(dim(input_data)[1]-1))**2)
    c1<-b1-1/a1
    c2<-b2-((nindiv+2)/(a1*nindiv))+(a2/a1**2)
    e1<-c1/a1
    e2<-c2/(a1**2+a2)
    S<-sum(apply(theta_matrix1,1,sum)!=0)
        
    theta_pi<-sum(apply(theta_matrix1,2,sum)*nromalized_factor)/
        (combination_times-sum(apply(!is.na(theta_matrix),2,sum)==0)
        )
    theta_w<-S/a1
    var_d<-(e1*S+e2*S*(S-1))**(1/2)
    
    tajimasd<-(theta_pi-theta_w)/var_d
    
    theta_pi_between<-
        sum(apply(theta_matrix1[,between_or_within_pop=="between"],2,sum)*nromalized_factor)/nbetween
    theta_pi_within<-
        sum(apply(theta_matrix1[,between_or_within_pop=="within"],2,sum)*nromalized_factor)/nbetween
    fst<-(theta_pi_between-theta_pi_within)/theta_pi_between
    return(list(tajimasd,fst))
}

4. 定义扫描基因组的sliding window的参数

##### define sliding window parameters
window_size=20 #### change this
step_wise=1  #### change this
combination_times<-choose(nindiv,2)
b1<-nindiv+1/3*(nindiv-1)
b2<-(2*(nindiv**2+nindiv+3))/(9*nindiv*(nindiv-1))
total_step=(nsnp-window_size)/step_wise
tajimad_list<-c()
fst_list<-c()
window_position<-matrix(nrow=total_step,ncol=2)

5. 启动 window sliding

##### run sliding windows
for(pace in 1:total_step){
    print(pace/total_step)
    start<-1+step_wise*(pace-1)
    end<-1+step_wise*(pace-1)+window_size
    res<-tajima_and_fst(data1[start:end,])  #### using the function
    new_d<-res[[1]] ### saving result of D
    new_fst<-res[[2]] ### saving result of fst
    tajimad_list<-c(tajimad_list,new_d)
    fst_list<-c(fst_list,new_fst)
    window_position[pace,]<-c(start,end)
}

6. 储存结果,画图

#### concate output result
out<-data.frame(chr=pos_data[,1][1],
                snp_position_start=pos_data[,2][window_position[,1]],
                snp_position_end=pos_data[,2][window_position[,2]],
                relative_start=window_position[,1],
                relative_end=window_position[,2],
                tajimasd=(tajimad_list-mean(tajimad_list))/sd(tajimad_list),  #### 这里标准化、中心化了
                fst=(fst_list-mean(fst_list))/sd(fst_list))  #### 这里标准化、中心化了

write.table(out,"chr18.tajimasd.fst.txt",sep="\t",quote = F,row.names = F)
head(out)
看一眼结果

7. 画图

library(ggplot2)
ggplot(data=out)+
    geom_point(aes(x=(snp_position_start+snp_position_end)/2,y=fst,color="fst"))
ggplot(data=out)+
geom_point(aes(x=(snp_position_start+snp_position_end)/2,y=tajimasd,color="tajimasd2"))
Tajima's D

Fst

暂时还没搞懂怎么计算P值...好像要序列模拟,比较麻烦,后面再思考。或者套个正态分布看离群值?但这样有点武断,而且没有假设检验。

Tajima原文中Tajimas' D和计算机序列模拟的比对结果。因此绝对值大于2应该睡rule of thumb,应该就算显著。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,029评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,238评论 3 388
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,576评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,214评论 1 287
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,324评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,392评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,416评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,196评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,631评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,919评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,090评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,767评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,410评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,090评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,328评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,952评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,979评论 2 351

推荐阅读更多精彩内容

  • 换装 HumanAIGC/OutfitAnyone: Outfit Anyone:适用于任何服装和任何人的超高品质...
    承诺一时的华丽阅读 717评论 0 0
  • 有言在先 不好意思,这可能是一篇水文(但绝对诚意之作),水性不好的同学请往后稍一稍,在岸边观望,让水性好的后浪们往...
    柊铉老师阅读 395评论 0 0
  • https://segmentfault.com/a/1190000039166040 | 黑客练手入门| pwn...
    星缘随风阅读 878评论 0 0
  • 当我们面对一个术语的时候,首要的原则就是「尊重知识的源头」。 比如当我们在知乎看到上面这则「费曼技巧」高赞回答的时...
    古严Pro阅读 921评论 2 1
  • 两种安装方式,一个是直接用下载FFmpeg库,解压拷贝到本地;二是用brew命令,直接安装FFmpeg。我用的第二...
    usuer阅读 840评论 0 0