Linux命令:纵向/横向合并文本 cat/paste

cat 和 paste 分别为linux中 纵向 以及 横向合并文本的命令

纵向合并 cat

cat 是 concatenate的缩略,其主要功能是查看文件或纵向合并文件。

对单个文件使用时为查看文件

-n 选项为显示行号

$ cat file1.txt 
1 apple
2 banana
3 pear
4 orange

#-n 第一列输出行号
$ cat -n file1.txt 
     1  1 apple
     2  2 banana
     3  3 pear
     4  4 orange

对多个文件使用时即为纵向合并

$ cat file1.txt 
1 apple
2 banana
3 pear
4 orange

$ cat file2.txt 
1 pear
2 apple
3 banana
5 kiwi

#查看文件1与文件2(也就是将两个文件纵向合并)
$ cat file1.txt file2.txt 
1 apple
2 banana
3 pear
4 orange
1 pear
2 apple
3 banana
5 kiwi

#文件名称仅有数字不同时可以使用以下简略写法
$ cat file[1-2].txt
1 apple
2 banana
3 pear
4 orange
1 pear
2 apple
3 banana
5 kiwi

cat的其他选项


-b	--number-nonblank	添加行号,但空白行不添加
-s	--squeeze-blank	将连续的空白行缩为一行
-v	--show-nonprinting	显示TAB、换行,分页以外的非表示文字
-t	―	显示非表示文字 tab以"^I"显示等
-E	--show-ends	行末以"$"表示
-A	--show-all	显示所有非表示文字(与-vET相同)
-e	―	显示除tab以外的非表示文字(与-vE相同)


横向合并 paste

paste 与cat类似,但是是 逐行 横向 合并(单纯合并,不进行连接,不改变行的顺序,连接的话用join命令)

#合并file1与file2 , 默认的分隔符为tab
$ paste file1.txt file2.txt 
1 apple 1 pear
2 banana        2 apple
3 pear  3 banana
4 orange        5 kiwi

#也可以使用简略写法
paste file[1-2].txt

-d可以指定合并后的分隔符

#指定分隔符为空格
$ paste -d' ' file1.txt file2.txt 
1 apple 1 pear
2 banana 2 apple
3 pear 3 banana
4 orange 5 kiwi

#指定分隔符为,
$ paste -d',' file1.txt file2.txt 
1 apple,1 pear
2 banana,2 apple
3 pear,3 banana
4 orange,5 kiwi

-s 可以实现按字段合并(按行横向合并的转置)

$ paste -d' ' -s file1.txt file2.txt 
1 apple 2 banana 3 pear 4 orange
1 pear 2 apple 3 banana 5 kiwi

Linux命令:连接表格 join

linux中join命令可以对两个相关联表格的文件以某一列为key进行连接。与sql数据库的join概念类似。

  1. Inner join
  2. Left, right, outer join
  3. 指定Key
  4. 指定输出的列
  5. 其它选项

内连接 Inner join

join 默认以第一列为key进行合并,并输出两个文件都有的行(内连接,inner join),最简单的用法如下所示 :

(**注意使用join前应当对要连接的文件使用sort事先进行排序)

$ cat file1.txt 
1 apple
2 banana
3 pear
4 orange

$ cat file2.txt 
1 pear x
2 apple y
3 banana z
5 kiwi q

$ join file1.txt file2.txt 
1 apple pear x
2 banana apple y
3 pear banana z

各种连接的概念示意图:

左/ 右 / 外连接 Left/right/outer join

-a N 输出指定第N个文件的所有行

通过-a选项可以完成left join,right join以及outer join的操作

单独指定-a 1 即为左连接(连接后输出第一个文件里所有的行)

单独指定 -a 2 即为右链接(连接后输出第二个文件里所有的行)

同时制定 -a 1 -a 2 为外连接(连接后输出两个文件里所有的行)

#left join
$ join -a 1 file1.txt file2.txt 
1 apple pear x
2 banana apple y
3 pear banana z
4 orange

#right join
$ join -a 2 file1.txt file2.txt 
1 apple pear x
2 banana apple y
3 pear banana z
5 kiwi q

#outer join
$ join -a 1 -a 2 file1.txt file2.txt 
1 apple pear x
2 banana apple y
3 pear banana z
4 orange
5 kiwi q

Key

join默认使用的key是第一列,

-j N 指定两个文件j合并时所使用的key为第N列

也可以单独指定:

-1 N 指定第一个文件所用key为第N列

-2 N 指定第一个文件所用key为第N列

-e [字符串] 指定的key不存在时,输出“字符串”代替

#因为没有以第二列为key进行排序,所以报错
$ join -j 2 file1.txt file2.txt 
join: file1.txt:4: is not sorted: 4 orange
join: file2.txt:2: is not sorted: 2 apple y
pear 3 1 x

#使用<(your command) 形式可以直接将 your command的结果作为输入
#使用排序后的结果则可以以第二列为key合并
join -j 2 <(sort -k 2 file1.txt)  <(sort -k 2 file2.txt)
apple 1 2 y
banana 2 3 z
pear 3 1 x

#-j 2的效果等同 -1 2 -2 2
join -1 2 -2 2 <(sort -k 2 file1.txt)  <(sort -k 2 file2.txt)
apple 1 2 y
banana 2 3 z
pear 3 1 x

#也可以使用-1 与-2 单独指定

#指定的key不存在时,输出“na”代替
$ join -j 4 -e na file1.txt file2.txt 
na 1 apple 1 pear x
na 1 apple 2 apple y
na 1 apple 3 banana z
na 1 apple 5 kiwi q
na 2 banana 1 pear x
na 2 banana 2 apple y
na 2 banana 3 banana z
na 2 banana 5 kiwi q
na 3 pear 1 pear x
na 3 pear 2 apple y
na 3 pear 3 banana z
na 3 pear 5 kiwi q
na 4 orange 1 pear x
na 4 orange 2 apple y
na 4 orange 3 banana z
na 4 orange 5 kiwi q

Output 指定输出的列

-o 选项可以指定输出的列

格式如下:

单列: ”文件序号.列序号“ ,如 1.1 为第1个文件的第1列

多列:“文件序号.{列序号1,列序号1…}” , 如1.{1,2} 为第1个文件的第1列与第2列

#join后输出第1个文件的第1列,与输出第2个文件的第1列
$ join -o 1.1 2.1 file1.txt file2.txt 
1 1
2 2
3 3
#join后输出第1个文件的第1列,与输出第2个文件的第1,2列
$ join -o 1.1 2.{1,2} file1.txt file2.txt
1 1 pear
2 2 apple
3 3 banana

其他常用的选项

-i 匹配时忽略大小写
--header 将第一行视为header,不进行匹配
-v [指定文件名] 输出与指定文件不一致的行
-t 分隔符 指定读取文件时的分隔符

比较目录1中哪些文件不在目录2中

# 仅比较文件名
join  -1 9  -2 9  -v 1 -o 1.9 <(ls -l directory1) <(ls -l directory2)

Linux命令:去除重复的行 uniq

uniq命令主要用于删除文件中重复的行,使用的前提是文件已经使用sort排序后,否则uniq只删除连续重复的行,而非全局删除重复。

主要使用场景:

去除重复的行 (可以忽略大小写)

统计重复的行

uniq的主要选项包括:

-c	--count	统计各行出现的次数
-u	--unique	只输出不重复的行
-d	--repeated	只输出重复的行
-D	--all-repeated	输出全部重复的行
-i	--ignore-case	比较时忽略大小写
-w N	--check-chars=N	只比较行的前N个字符
-s N	--skip-chars=N	比较时略过前N个字符,之比较N个字符后的内容
-f N	--skip-fields=N	比较时略过前N个字段,之比较N个字段后的内容

以以下的文件为例

$ cat test_data.txt 
green
red
white
blue
yellow
black
white
blue
blue

对没有sort排序的文件使用uniq,只删除连续重复的行(两个blue变为一个)

$ uniq test_data.txt 
green
red
white
blue
yellow
black
white
blue

先sort后,再uniq即可全局删除重复 (删去了多余的blue和white)

$ sort test_data.txt | uniq
black
blue
green
red
white
yellow

使用-c可以统计行的重复次数

$ sort test_data.txt | uniq -c
      1 black
      3 blue
      1 green
      1 red
      2 white
      1 yellow

$ sort test_data.txt | uniq -c | sort
      1 black
      1 green
      1 red
      1 yellow
      2 white
      3 blue

使用-w可以只对前n个字符为对象进行删除 ,若n=1 , blue与black 则视为重复:

$ sort test_data.txt | uniq -w 1
black
green
red
white
yellow

Linux命令:排序 sort

sort 是对文件的行进行排序的命令。

常用选项如下:

-f	--ignore-case	不区分大小写
-n	--numeric-sort	视为数值进行排列
-r	--reverse	逆序排列 (从大到小)
-k 指定	--key=指定	指定排序所依据的字段及选项 
-t 文字	--field-separator=文字	指定区分字段的分隔符

以以下文件为例:

$ cat sort_data.txt 
1 a
8 b
3 d
12 c

#默认为以第一列为key 按字符排序
$ sort sort_data.txt 
12 c
1 a
3 d
8 b

#指定-n后以数字大小排序
$ sort -n sort_data.txt 
1 a
3 d
8 b
12 c

指定-r选项后可以逆序排列

$ sort -r sort_data.txt 
8 b
3 d
1 a
12 c

$ sort -nr sort_data.txt 
12 c
8 b
3 d
1 a

-k可以指定排序依据的列

$ sort -k 2 sort_data.txt 
1 a
8 b
12 c
3 d

$ sort -k 2r sort_data.txt 
3 d
12 c
8 b
1 a

-t 指定分隔列的分隔符

$ cat sort_data.csv 
1,4
8,2
3,1
12,13

$ sort -k 2nr -t , sort_data.csv 
12,13
1,4
8,2
3,1

Linux 命令:查看文件开头与末尾 head 与 tail

head 与 tail 分别为显示文件开头以及末尾的命令,是linux最常用的命令之一:

主要有以下选项:

-n 显示的行数
-v verbose 输出文件名的header
-q 不输出文件名的header
-f follow tail专用,可以实时监控文件末尾

以以下有11行的示例数据为例 head 默认可以查看文件的前十行:

$ cat test.txt 
a 1
b 2
c 3
d 4
e 5
f 6
g 7
h 8
i 9
j 10
k 11

#head 查看开头,默认为十行
$ head test.txt 
a 1
b 2
c 3
d 4
e 5
f 6
g 7
h 8
i 9
j 10

#tail 查看末尾,默认为十行
$ tail test.txt
b 2
c 3
d 4
e 5
f 6
g 7
h 8
i 9
j 10
k 11

head与 tail 使用 -n 选项可以 指定显示的行数

$ head -n 5 test.txt 
a 1
b 2
c 3
d 4
e 5

tail -n 5 test.txt
g 7
h 8
i 9
j 10
k 11

-v verbose 输出时第一行显示文件名

head -v test.txt 
==> test.txt <==
a 1
b 2
c 3
d 4
e 5
f 6
g 7
h 8
i 9
j 10


head , tail可以对多个文件使用

head test.txt test2.txt 
==> test.txt <==
a 1
b 2
c 3
d 4
e 5
f 6
g 7
h 8
i 9
j 10

==> test2.txt <==
aaaaaa 123
aaaaab 234
aaabcd 345

使用-q (quiet)则不显示header

head -q test.txt test2.txt 
a 1
b 2
c 3
d 4
e 5
f 6
g 7
h 8
i 9
j 10
aaaaaa 123
aaaaab 234
aaabcd 345

-f (follow) tail有一个额外的选项,可以实时监控文件的末尾(例如监视一个实时输出的log文件)

tail -f test.log

head 与tail组合 可以查看文件的任意行

$ head -n 7 test.txt |tail -n 1
g 7

Linux命令:替换与删除 tr

tr 在linux命令中是 translate的缩略,主要用于对单个字符的替换或是删除 (作用对象是单个字符,或字符集,不能替换单词)

tr的语法
tr [选项] 文字集1 [文字集2]
-d	--delete	删除包含在字符集里的字符
-s	--squeeze-repeats	压缩包含在字符集里的字符
-c	--complement	对象为字符集以外的字符

tr 不能直接输入文件名,需要使用管道 | 输入数据

下面的例子中将文件里的a,b,c,替换为1,2,3

$ cat test.txt 
abc 1
bcd 2
cde 3
def 4
efg 5

$ cat test.txt | tr abc 012
012 1
12d 2
2de 3
def 4
efg 5

可以使用A-Z等缩略形式,下面的例子将文件中小写字母转换成大写字母

$ cat test.txt | tr a-z A-Z
ABC 1
BCD 2
CDE 3
DEF 4
EFG 5

压缩多个相同字符 (-s)

-s 选项可以压缩多个相同字符为一个,可以用来消除多余空格等操作

$ cat test2.txt 
aaaaaa 123
aaaaab 234
aaabcd 345

$cat test2.txt | tr -s a 
a 123
ab 234
abcd 345

删除字符 (-d)

-d 选项可以删除指定的字符

$ cat test2.txt | tr -d a 
 123
b 234
bcd 345

Linux命令:提取列 cut

cut命令可用来提取文件中某一列或某些列, 列的定义可以通过字节(bytes, -b)数,字符(character, -c)数,或者字段(field, -f)数, 这三种定义分别对应以下三种选项,使用时必须指定其一:

-b bytes
-c character
-f field

如果不指定的话会报错
cut test.txt 
cut: you must specify a list of bytes, characters, or fields
Try 'cut --help' for more information.

单列提取

$cat test.txt 
abc 1
bcd 2
cde 3
def 4
efg 5

#提取第二列(字节)
$ cut -c 2 test.txt 
b
c
d
e
f

#提取第二列(字符)
$ cut -b 2 test.txt 
b
c
d
e
f

#提取第二列(字段)
cut -f 2 -d ' ' test.txt 
1
2
3
4
5

注: 使用 -f 时可以通过-d 指定分隔符

多列提取 (以 -b 为例,-c,-f 一样)

可以以 间隔要选取的列,例如 -b 1,3,也可以通过-指定范围,如-b 1-3,或是两者组合,-b 1-3,5

当要选取从0到第N列时,可以用 -b -N ,第N列到末尾可以用-b N-

(注:这里的区间全部都为闭区间,即包含起点以及终点的列)

cut -b 1,3 test.txt 
ac
bd
ce
df
eg

cut -b 1-3 test.txt 
abc
bcd
cde
def
efg

cut -b 1-3,5 test.txt 
abc1
bcd2
cde3
def4
efg5

$ cut -b -2 test.txt 
ab
bc
cd
de
ef

cut -b 2- test.txt 
bc 1
cd 2
de 3
ef 4
fg 5

多文件提取

cut可以同时对多个文件进行提取,输出时纵向连接

$ cat test.txt 
abc 1
bcd 2
cde 3
def 4
efg 5

$ cat test2.txt 
abc 123
bcd 234
cde 345

$cut -b 2 test.txt test2.txt 
b
c
d
e
f
b
c
d

Linux命令:逆序输出 tac 与 rev

tac 和 rev 命令都是将文件逆序输出的命令:

tac : 从最后一行开始,以整行为单位逆序输出 (行内内容不变,行顺序颠倒)

rev : 对文件的各个行的文字,逐一逆序输出 (行内内容倒序,行顺序不变)

tac 示例如下:

$ cat test.txt 
a 1
b 2
c 3
d 4
e 5
f 6
g 7
h 8
i 9
j 10

$ tac test.txt 
j 10
i 9
h 8
g 7
f 6
e 5
d 4
c 3
b 2
a 1


类似cat,tac也可以建多个文件逆序输出的结果拼接

cat test2.txt 
abc 123
bcd 234
cde 345

tac test.txt test2.txt 
j 10
i 9
h 8
g 7
f 6
e 5
d 4
c 3
b 2
a 1
cde 345
bcd 234
abc 123

rev的示例如下

$ rev test.txt
1 a
2 b
3 c
4 d
5 e
6 f
7 g
8 h
9 i
01 j

当然可以将tac与rev结合管道使用,完成倒背如流式输出

tac test.txt |rev
01 j
9 i
8 h
7 g
6 f
5 e
4 d
3 c
2 b
1 a

附录:tac 的选项

-s 	--separator=分隔符(默认为换行)
-r	--regex	使用正则表达式匹配分隔符

孟德尔随机化系列之二:两样本MR – TwoSampleMR

目录

  1. TwoSampleMR简介
  2. TwoSampleMR简要教程
    1. 方法概览
    2. 读取暴露GWAS数据,选取工具变量
    3. 读取结局GWAS数据,提取对应工具变量
    4. 对数据进行预处理,使其效应等位与效应量保持统一
    5. MR分析与可视化
      1. MR分析
      2. 敏感性分析
      3. 散点图
      4. 森林图
      5. 漏斗图
  3. 参考

TwoSampleMR简介

两样本孟德尔随机化(Two sample Mendelian randomisation,2SMR)是使用GWAS概括性数据估计暴露对结果的因果效应的一种方法。尽管孟德尔随机化在概念上相对直观简单,但实际操作却相对繁琐,有很多细节需要注意。TwoSampleMR就是一款致力于简化MR分析的R包,其整合了以下的分析步骤:

  1. 数据管理与统一
  2. 因果推断的常规统计学分析
  3. 接入了GWAS概括性数据的数据库,使分析更为便捷

孟德尔随机化的原理可以参考G. Davey Smith and Ebrahim 2003; George Davey Smith and Hemani 2014, 统计方法可以参考Pierce and Burgess 2013; Bowden, Davey Smith, and Burgess 2015等。

TwoSampleMR简要教程

本文仅对TwoSampleMR使用方法进行介绍。基础概念概念可以参考:GWASLab:孟德尔随机化系列之一:基础概念 Mendelian randomization I

下载(注:本文所用语言均为R)

TwoSampleMR官网: https://mrcieu.github.io/TwoSampleMR/

TwoSampleMR是一个R包,可以通过以下代码在R中直接安装

install.packages("remotes")
remotes::install_github("MRCIEU/TwoSampleMR")

0 方法概览

MR分析的主要步骤如下:

  1. 读取暴露因素GWAS数据
  2. 选取合适的工具变量(如有必要,需要进行clumping)
  3. 读取结局GWAS数据,提取上述的工具变量的SNP
  4. 对暴露因素与结局的GWAS数据进行预处理,使其格式统一
  5. 采用选中的MR方法进行分析
  6. 将结果可视化
    1. 散点图
    2. 森林图
    3. 漏斗图

1 读取暴露GWAS数据,选取工具变量

1.1 读取数据

对于暴露因素的GWAS数据,TwoSampleMR需要一个工具变量的data frame,每行对应一个SNP,至少需要4列,分别为:

  • SNP – rs ID
  • beta – The effect size. If the trait is binary then log(OR) should be used
  • se – The standard error of the effect size
  • effect_allele – The allele of the SNP which has the effect marked in beta

其他可能有助于MR预处理或分析的列包括

  • other_allele – The non-effect allele
  • eaf – The effect allele frequency
  • Phenotype – The name of the phenotype for which the SNP has an effect

你也可以提供额外的信息(可选,对于分析非必须)

  • chr – Physical position of variant (chromosome)
  • position – Physical position of variant (position)
  • samplesize – Sample size for estimating the effect size
  • ncase – Number of cases
  • ncontrol – Number of controls
  • pval – The P-value for the SNP’s association with the exposure
  • units – The units in which the effects are presented
  • gene – The gene or other annotation for the the SNP

本教程将从本地文本文件中读取暴露GWAS数据:

本文使用的暴露因素的GWAS数据的前5行如下所示:

rsid,effect,SE,a1,a2,a1_freq,p-value,Units,Gene,n
rs10767664,0.19,0.030612245,A,T,0.78,5.00E-26,kg/m2,BDNF,225238
rs13078807,0.1,0.020408163,G,A,0.2,4.00E-11,kg/m2,CADM2,221431
rs1514175,0.07,0.020408163,A,G,0.43,8.00E-14,kg/m2,TNNI3K,207641
rs1558902,0.39,0.020408163,A,T,0.42,5.00E-120,kg/m2,FTO,222476

该示例数据随TwoSampleMR包一同下载,可以通过以下代码定位其位置,并读取:

## 定位数据位置,将路径赋予bmi2_file
bmi2_file <- system.file("extdata/bmi.csv", package="TwoSampleMR")

##读取数据
bmi_exp_dat <- read_exposure_data(
    filename = bmi2_file,
    sep = ",",
    snp_col = "rsid",
    beta_col = "effect",
    se_col = "SE",
    effect_allele_col = "a1",
    other_allele_col = "a2",
    eaf_col = "a1_freq",
    pval_col = "p-value",
    units_col = "Units",
    gene_col = "Gene",
    samplesize_col = "n"
)

1.2 Clumping

对于一个标准的两样本MR分析来说,我们需要确保工具变量之间是互相独立的(即不存在显著的LD),在读取完数据后我们应当对其进行LD Clumping,这里可以使用clump_data()函数,指定LD参考面板为EUR,r2的阈值为0.01,对数据进行Clumping。 该函数与OpenGWAS API进行交互,其存储了千人基因组中5个群体(EUR, SAS, EAS, AFR, AMR)的LD数据。对东亚人进行分析时指定pop = "EAS"即可。

bmi_exp_dat <- clump_data(bmi_exp_dat,clump_r2=0.01 ,pop = "EUR")
#> Please look at vignettes for options on running this locally if you need to run many instances of this command.
#> Clumping UVOe6Z, 30 variants, using EUR population reference
#> Removing 3 of 30 variants due to LD with other variants or absence from LD reference panel

2 读取结局GWAS数据,提取对应工具变量

结局数据可以像上一节暴露因素GWAS数据的读取一样从本地文件中读取,也可以从在线数据库中提取。因为上一节已经演示过本地数据的读取,在这里就演示从在线数据库中提取的方法, 使用extract_outcome_data函数,指定结局GWAS的id,与要提取的SNP的rsID,即可完成数据提取。

例如我们想分析BMI与冠心病(coronary heart disease)之间的因果关系,首先我们要查找冠心病GWAS在数据库中的id

2.1 查找相应的GWAS

使用available_outcomes()可以查看当前可用的所有表型的GWAS数据,然后使用grep1抓取关键字

ao <- available_outcomes()
#> API: public: <http://gwas-api.mrcieu.ac.uk/>
head(ao)
#> # A tibble: 6 x 22
#>   id      trait     group_name  year consortium author sex   population    unit 
#>   <chr>   <chr>     <chr>      <int> <chr>      <chr>  <chr> <chr>         <chr>
#> 1 ieu-b-~ Number o~ public      2021 MRC-IEU    Clare~ Male~ European      SD   
#> 2 prot-a~ Leptin r~ public      2018 NA         Sun BB Male~ European      NA   
#> 3 prot-a~ Adapter ~ public      2018 NA         Sun BB Male~ European      NA   
#> 4 ukb-e-~ Impedanc~ public      2020 NA         Pan-U~ Male~ Greater Midd~ NA   
#> 5 prot-a~ Dual spe~ public      2018 NA         Sun BB Male~ European      NA   
#> 6 eqtl-a~ ENSG0000~ public      2018 NA         Vosa U Male~ European      NA   
#> # ... with 13 more variables: sample_size <int>, nsnp <int>, build <chr>,
#> #   category <chr>, subcategory <chr>, ontology <chr>, note <chr>, mr <int>,
#> #   pmid <int>, priority <int>, ncase <int>, ncontrol <int>, sd <dbl>

## 使用grep1抓取目标表型
ao[grepl("heart disease", ao$trait), ]
#> # A tibble: 28 x 22
#>    id      trait       group_name  year consortium author sex   population unit 
#>    <chr>   <chr>       <chr>      <int> <chr>      <chr>  <chr> <chr>      <chr>
#>  1 ieu-a-8 Coronary h~ public      2011 CARDIoGRAM Schun~ Male~ European   log ~
#>  2 finn-a~ Valvular h~ public      2020 NA         NA     Male~ European   NA   
#>  3 finn-a~ Other or i~ public      2020 NA         NA     Male~ European   NA   
#>  4 ukb-b-~ Diagnoses ~ public      2018 MRC-IEU    Ben E~ Male~ European   SD   
#>  5 ukb-a-~ Diagnoses ~ public      2017 Neale Lab  Neale  Male~ European   SD   
#>  6 ukb-e-~ I25 Chroni~ public      2020 NA         Pan-U~ Male~ South Asi~ NA   
#>  7 ukb-b-~ Diagnoses ~ public      2018 MRC-IEU    Ben E~ Male~ European   SD   
#>  8 finn-a~ Ischemic h~ public      2020 NA         NA     Male~ European   NA   
#>  9 finn-a~ Major coro~ public      2020 NA         NA     Male~ European   NA   
#> 10 finn-a~ Other hear~ public      2020 NA         NA     Male~ European   NA   
#> # ... with 18 more rows, and 13 more variables: sample_size <int>, nsnp <int>,
#> #   build <chr>, category <chr>, subcategory <chr>, ontology <chr>, note <chr>,
#> #   mr <int>, pmid <int>, priority <int>, ncase <int>, ncontrol <int>, sd <dbl>

查看完整结果后我们发现冠心病GWAS id为 ieu-a-7

当然可以直接进入数据库网站搜索 https://gwas.mrcieu.ac.uk/ ,简单直观

2.2 提取结局GWAS数据

指定GWAS id,指定要提取的SNP rsid (1中选取的工具变量),使用extract_outcome_data进行提取

chd_out_dat <- extract_outcome_data(
    snps = bmi_exp_dat$SNP,
    outcomes = 'ieu-a-7'
)

head(chd_out_dat )
A data.frame: 6 × 16
SNP	chr	pos	beta.outcome	se.outcome	samplesize.outcome	pval.outcome	eaf.outcome	effect_allele.outcome	other_allele.outcome	outcome	id.outcome	originalname.outcome	outcome.deprecated	mr_keep.outcome	data_source.outcome
<chr>	<chr>	<chr>	<dbl>	<dbl>	<dbl>	<dbl>	<dbl>	<chr>	<chr>	<chr>	<chr>	<chr>	<chr>	<lgl>	<chr>
1	rs887912	2	59302877	-0.021960	0.0111398	184305	0.04868780	0.731654	C	T	Coronary heart disease || id:ieu-a-7	ieu-a-7	Coronary heart disease	Coronary heart disease || ||	TRUE	igd
2	rs2112347	5	75015242	-0.005855	0.0096581	184305	0.54436400	0.401399	G	T	Coronary heart disease || id:ieu-a-7	ieu-a-7	Coronary heart disease	Coronary heart disease || ||	TRUE	igd
3	rs3817334	11	47650993	0.000355	0.0095386	184305	0.97031200	0.387831	T	C	Coronary heart disease || id:ieu-a-7	ieu-a-7	Coronary heart disease	Coronary heart disease || ||	TRUE	igd
4	rs1555543	1	96944797	0.002516	0.0093724	184305	0.78835500	0.558318	C	A	Coronary heart disease || id:ieu-a-7	ieu-a-7	Coronary heart disease	Coronary heart disease || ||	TRUE	igd
5	rs2815752	1	72812440	0.010402	0.0098384	184305	0.29038200	0.611282	A	G	Coronary heart disease || id:ieu-a-7	ieu-a-7	Coronary heart disease	Coronary heart disease || ||	TRUE	igd
6	rs10938397	4	45182527	0.030606	0.0093485	184305	0.00106079	0.416076	G	A	Coronary heart disease || id:ieu-a-7	ieu-a-7	Coronary heart disease	Coronary heart disease || ||	TRUE	igd

3 对数据进行预处理,使其效应等位与效应量保持统一

完成暴露因素与结局GWAS数据的提取后,我们要对其进行预处理,使其效应等位保持统一,可以使用harmonise_data函数,方便的完成处理:

dat <- harmonise_data(
    exposure_dat = bmi_exp_dat, 
    outcome_dat = chd_out_dat
)

到这一步数据的准备工作就完成了,下一步可以开始分析

4 MR分析与可视化

4.1 MR分析

使用mr函数对处理好的数据dat 进行分析,结果如下

res <- mr(dat)
#> Analysing 'ieu-a-2' on 'ieu-a-7'
res
#>   id.exposure id.outcome                              outcome
#> 1     ieu-a-2    ieu-a-7 Coronary heart disease || id:ieu-a-7
#> 2     ieu-a-2    ieu-a-7 Coronary heart disease || id:ieu-a-7
#> 3     ieu-a-2    ieu-a-7 Coronary heart disease || id:ieu-a-7
#> 4     ieu-a-2    ieu-a-7 Coronary heart disease || id:ieu-a-7
#> 5     ieu-a-2    ieu-a-7 Coronary heart disease || id:ieu-a-7
#>                        exposure                    method nsnp         b
#> 1 Body mass index || id:ieu-a-2                  MR Egger   79 0.5024935
#> 2 Body mass index || id:ieu-a-2           Weighted median   79 0.3870065
#> 3 Body mass index || id:ieu-a-2 Inverse variance weighted   79 0.4459091
#> 4 Body mass index || id:ieu-a-2               Simple mode   79 0.3401554
#> 5 Body mass index || id:ieu-a-2             Weighted mode   79 0.3888249
#>           se         pval
#> 1 0.14396056 8.012590e-04
#> 2 0.07226598 8.541141e-08
#> 3 0.05898302 4.032020e-14
#> 4 0.15698810 3.330579e-02
#> 5 0.09240475 6.833558e-05

mr默认使用五种方法( MR Egger,Weighted median,Inverse variance weighted,Simple mode ,Weighted mode )

但我们可以额外指定方法,使用mr_method_list()查看当前支持的统计方法

mr_method_list()

obj	name	PubmedID	Description	use_by_default	heterogeneity_test
<chr>	<chr>	<chr>	<chr>	<lgl>	<lgl>
mr_wald_ratio	Wald ratio			TRUE	FALSE
mr_two_sample_ml	Maximum likelihood			FALSE	TRUE
mr_egger_regression	MR Egger	26050253		TRUE	TRUE
mr_egger_regression_bootstrap	MR Egger (bootstrap)	26050253		FALSE	FALSE
mr_simple_median	Simple median			FALSE	FALSE
mr_weighted_median	Weighted median			TRUE	FALSE
mr_penalised_weighted_median	Penalised weighted median			FALSE	FALSE
mr_ivw	Inverse variance weighted			TRUE	TRUE
mr_ivw_radial	IVW radial			FALSE	TRUE
mr_ivw_mre	Inverse variance weighted (multiplicative random effects)			FALSE	FALSE
mr_ivw_fe	Inverse variance weighted (fixed effects)			FALSE	FALSE
mr_simple_mode	Simple mode			TRUE	FALSE
mr_weighted_mode	Weighted mode			TRUE	FALSE
mr_weighted_mode_nome	Weighted mode (NOME)			FALSE	FALSE
mr_simple_mode_nome	Simple mode (NOME)			FALSE	FALSE
mr_raps	Robust adjusted profile score (RAPS)			FALSE	FALSE
mr_sign	Sign concordance test		Tests for concordance of signs between exposure and outcome	FALSE	FALSE
mr_uwr	Unweighted regression		Doesn't use any weights	FALSE	TRUE

在mr函数中,添加想要使用的方法即可:

mr(dat, method_list=c("mr_egger_regression", "mr_ivw"))
#> Analysing 'ieu-a-2' on 'ieu-a-7'
#>   id.exposure id.outcome                              outcome
#> 1     ieu-a-2    ieu-a-7 Coronary heart disease || id:ieu-a-7
#> 2     ieu-a-2    ieu-a-7 Coronary heart disease || id:ieu-a-7
#>                        exposure                    method nsnp         b
#> 1 Body mass index || id:ieu-a-2                  MR Egger   79 0.5024935
#> 2 Body mass index || id:ieu-a-2 Inverse variance weighted   79 0.4459091
#>           se        pval
#> 1 0.14396056 8.01259e-04
#> 2 0.05898302 4.03202e-14

4.2 敏感性分析

4.2.1 异质性检验 mr_heterogeneity

mr_heterogeneity(dat)
#>   id.exposure id.outcome                              outcome
#> 1     ieu-a-2    ieu-a-7 Coronary heart disease || id:ieu-a-7
#> 2     ieu-a-2    ieu-a-7 Coronary heart disease || id:ieu-a-7
#>                        exposure                    method        Q Q_df
#> 1 Body mass index || id:ieu-a-2                  MR Egger 143.3046   77
#> 2 Body mass index || id:ieu-a-2 Inverse variance weighted 143.6508   78
#>         Q_pval
#> 1 6.841585e-06
#> 2 8.728420e-06

4.2.2 水平多效性检验 mr_pleiotropy_test

MR Egger 回归中的截距是反应水平多效性的一个有效指标,可以通过mr_pleiotropy_test计算

mr_pleiotropy_test(dat)
#>   id.exposure id.outcome                              outcome
#> 1     ieu-a-2    ieu-a-7 Coronary heart disease || id:ieu-a-7
#>                        exposure egger_intercept          se      pval
#> 1 Body mass index || id:ieu-a-2    -0.001719304 0.003985962 0.6674266

4.3 可视化

4.3.1 散点图

对上述的MR结果与输入数据,使用mr_scatter_plot函数绘制散点图

res <-mr(dat)
#> Analysing 'ieu-a-2' on 'ieu-a-7'
p1 <-mr_scatter_plot(res, dat)

4.3.2 森林图

首先使用mr_singlesnp获取单个SNP的结果,然后使用mr_forest_plot绘制森林图

res_single <- mr_singlesnp(dat)
p2 <- mr_forest_plot(res_single)
p2[[1]]
#> Warning: Removed 1 rows containing missing values (geom_errorbarh).
#> Warning: Removed 1 rows containing missing values (geom_point).

4.3.2 漏斗图

首先使用mr_singlesnp获取单个SNP的结果,然后使用mr_funnel_plot绘制漏斗图

res_single <- mr_singlesnp(dat)
p4 <- mr_funnel_plot(res_single)
p4[[1]]

参考:

Hemani G, Tilling K, Davey Smith G (2017) Orienting the causal relationship between imprecisely measured traits using GWAS summary data. PLOS Genetics 13(11): e1007081. https://doi.org/10.1371/journal.pgen.1007081

Hemani G, Zheng J, Elsworth B, Wade KH, Baird D, Haberland V, Laurin C, Burgess S, Bowden J, Langdon R, Tan VY, Yarmolinsky J, Shihab HA, Timpson NJ, Evans DM, Relton C, Martin RM, Davey Smith G, Gaunt TR, Haycock PC, The MR-Base Collaboration. The MR-Base platform supports systematic causal inference across the human phenome. eLife 2018;7:e34408. doi: 10.7554/eLife.34408

https://mrcieu.github.io/TwoSam

多基因风险分数 PRS( Polygenic risk score)系列之六:metaGRS介绍

目录

  1. PRS回顾
  2. 为什么要构建metaGRS
  3. metaGRS构建方法
  4. 总结
  5. 参考

回顾

  1. GWASLab:多基因风险分数 PRS( Polygenic risk score)系列之一:概念入门
  2. GWASLab:多基因风险分数 PRS( Polygenic risk score)系列之二:使用PLINK计算PRS(C+T方法)
  3. GWASLab:多基因风险分数 PRS( Polygenic risk score)系列之三:使用PRSice计算PRS(C+T方法)
  4. ldpred2 (预留链接)
  5. prs-cs(预留链接)

为什么要构建metaGRS

以往的PRS研究中,PRS模型通常以单一的GWAS概括性数据为基础进行计算,但此方法往往不能达到较高的预测能力,主要是因为

  1. 有限的样本量
  2. 目标表型较为显著的异质性
  3. 对基因组覆盖的不完全
  4. 基因定型与插补存在较大不确定性

等原因。

在存在上述问题的情况下使用单一PRS进行预测会降低准确度,为了解决以上描述的问题,Michael Inouye等人最早在冠状动脉疾病(CAD)的预测中,引入了metaGRS的概念,类似于meta分析,meGRS将多个GRS进行合并得到metaGRS,以提升其风险预测能力。

metaGRS构建方法

本文以 Abraham,G等人在2019年发表的论文为例,简要介绍metaGRS的构建方法:

第一步:常规的单一PRS的计算

第二步:使用弹性网络来构建metaGRS,具体步骤如下所示

例如,Abraham,G等人构建的对IS缺血性中风的metaGRS中,纳入了如下的GRS,包括了AS(所有中风),以及中风的各个亚型(IS, SVS, LAS, CES),以及各个中风的风险因子(例如血压,BMI,2型糖尿病,冠状动脉疾病等)的GRS

注:弹性网络 elastic net:

在损失函数中同时加入L1 (Lasso回顾)与L2(Ridge回归)的正则项:

该计算可以通过R包glmnet实现

https://cran.r-project.org/web/packages/glmnet/index.html

第三步:最后和单一PRS时一样,需要使用独立样本对metaGRS进行验证


总结

目前使用metaGRS的研究还比较少,且集中于特定的表型(CAD和IS),但可以预计随着PRS研究数量不断增加,在未来metaGRS的应用也会随之增加。

参考

Inouye, Michael, et al. “Genomic risk prediction of coronary artery disease in 480,000 adults: implications for primary prevention.” Journal of the American College of Cardiology 72.16 (2018): 1883-1893.

Abraham, G., Malik, R., Yonova-Doing, E. et al. Genomic risk score offers predictive performance comparable to clinical risk factors for ischaemic stroke. Nat Commun 10, 5819 (2019). https://doi.org/10.1038/s41467-019-13848-1

Friedman, Jerome, Trevor Hastie, and Rob Tibshirani. “glmnet: Lasso and elastic-net regularized generalized linear models.” R package version 1.4 (2009): 1-24.