├── clean_drugbank.R ├── drug_targets.R ├── LICENSE ├── func_group_MR.R ├── config.R ├── sensitivity_instrument_overlap.R ├── clean_bnf.R ├── README.md ├── supplementary_tables.R ├── analysis_mr_exp_sbp.R ├── analysis_mr_sbp_ad.R ├── func_MR.R ├── sensitivity_gill.R ├── output_mr_exp_sbp.R ├── sensitivity_common_data.R └── output_mr_sbp_ad.R /clean_drugbank.R: -------------------------------------------------------------------------------- 1 | # Required libraries: readxl,data.table,tidyverse 2 | 3 | clean_drugbank <- function() { 4 | 5 | vocab <- read_csv("data/drugbank/drugbank_vocab.csv") 6 | vocab$substance <- paste0(vocab$`Common name`," | ",vocab$Synonyms) 7 | vocab <- vocab[,c("DrugBank ID","substance")] 8 | colnames(vocab) <- c("drugbank_id","substance") 9 | vocab$substance <- gsub(" \\| ",";",vocab$substance) 10 | vocab <- separate_rows(vocab,substance,sep = ";") 11 | 12 | active <- read_csv("data/drugbank/drug_target_identifiers_all_pharmacologically_active_v5.1.1.csv") 13 | active <- active[,c("Gene Name","Drug IDs")] 14 | colnames(active) <- c("gene","drugbank_id") 15 | active <- separate_rows(active, drugbank_id) 16 | 17 | df <- merge(vocab,active,by = c("drugbank_id"),all.x = TRUE) 18 | 19 | df <- df[df$substance!="NA",] 20 | df$substance <- tolower(df$substance) 21 | df <- unique(df) 22 | 23 | return(df) 24 | 25 | } -------------------------------------------------------------------------------- /drug_targets.R: -------------------------------------------------------------------------------- 1 | bnf <- clean_bnf() 2 | drugbank <- clean_drugbank() 3 | drug_targets <- merge(bnf,drugbank,all.x = TRUE) 4 | 5 | # Supplementary table 1 ======================================================= 6 | 7 | st1 <- unique(drug_targets) 8 | 9 | st1$gene <- ifelse(is.na(st1$gene),"",st1$gene) 10 | 11 | st1 <- st1 %>% 12 | group_by(drug,substance,drugbank_id) %>% 13 | summarise_all(funs(paste(., collapse=";"))) 14 | 15 | write.xlsx(data.frame(st1), file="output/Supplementary_Tables_AntihypertensivesMR.xlsx", 16 | sheetName="ST1",append=TRUE, row.names = FALSE, showNA = FALSE) 17 | 18 | # Match drug substances with targets ========================================== 19 | 20 | drug_targets <- drug_targets[!is.na(drug_targets$gene),] 21 | 22 | # Restrict to unique drug-gene pairs ========================================== 23 | 24 | drug_targets <- drug_targets[,c("drug","gene")] 25 | drug_targets <- unique(drug_targets) 26 | 27 | # Save output ================================================================= 28 | 29 | write.csv(drug_targets,file="data/drug_targets.csv",row.names = FALSE) -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Venexia Walker 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /func_group_MR.R: -------------------------------------------------------------------------------- 1 | # Required libraries: TwoSampleMR, tidyverse, furrr 2 | # For group MR a backend must be specified from the future package. 3 | # For sequential use plan(sequential) and for multicore plan(multiprocess). 4 | 5 | group_MR <- function (df, outcome.data = NULL, outcome = NULL, ...) { 6 | 7 | group_var <- quos(...) 8 | 9 | # Add unique ID to dataframe for grouping variables 10 | 11 | group_df <- df %>% 12 | as_tibble() %>% 13 | mutate(index = group_indices(df, !!!group_var)) 14 | 15 | # Perform MR function for each group 16 | 17 | if (outcome.data=="mrbase") { 18 | 19 | output <- group_df %>% 20 | group_by(index) %>% 21 | nest() %>% 22 | mutate(output = future_map(data, ~ suppressMessages(MR(., outcome = outcome, wait = TRUE)), .progress = TRUE)) %>% 23 | dplyr::select(index, output) %>% 24 | unnest(output) 25 | 26 | } 27 | 28 | if (outcome.data=="file") { 29 | 30 | output <- group_df %>% 31 | group_by(index) %>% 32 | nest() %>% 33 | mutate(output = future_map(data, ~ suppressMessages(MR_file(., outcome = outcome, wait = TRUE)), .progress = TRUE)) %>% 34 | dplyr::select(index, output) %>% 35 | unnest(output) 36 | 37 | } 38 | 39 | output <- group_df %>% 40 | dplyr::select(index = index, !!!group_var) %>% 41 | distinct() %>% 42 | full_join(output, by = "index") %>% 43 | dplyr::select(index, !!!group_var, everything()) 44 | 45 | return(output) 46 | 47 | } 48 | 49 | -------------------------------------------------------------------------------- /config.R: -------------------------------------------------------------------------------- 1 | # Set working directory ======================================================= 2 | 3 | setwd("") 4 | rm(list=ls()) 5 | graphics.off() 6 | 7 | # Load libraries ============================================================== 8 | 9 | if (!require(pacman)) install.packages("pacman"); library(pacman) 10 | p_load("xlsx") 11 | p_load("data.table") 12 | p_load("furrr") 13 | p_load("dplyr") 14 | p_load("ggplot2") 15 | p_load("tibble") 16 | p_load("tidyr") 17 | p_load("purrr") 18 | p_load("readr") 19 | p_load("forcats") 20 | p_load("biomaRt") 21 | p_load_gh("MRCIEU/TwoSampleMR") 22 | p_load_gh("MRCIEU/MRInstruments") 23 | p_load_gh("slowkow/proxysnps") 24 | 25 | # Load functions ============================================================== 26 | 27 | source("code/func_MR.R") 28 | source("code/func_group_MR.R") 29 | source("code/clean_drugbank.R") 30 | source("code/clean_bnf.R") 31 | 32 | # Setup parrallelization ====================================================== 33 | 34 | plan(multiprocess) 35 | 36 | # Remove supplementary tables file ============================================ 37 | 38 | if (file.exists("output/Supplementary_Tables_AntihypertensivesMR.xlsx")) { 39 | file.remove("output/Supplementary_Tables_AntihypertensivesMR.xlsx") 40 | } 41 | 42 | # Identify drug targets ======================================================= 43 | 44 | source("code/drug_targets.R") 45 | 46 | # Instrument selection ======================================================== 47 | 48 | source("code/analysis_mr_exp_sbp.R") 49 | 50 | # Main analysis =============================================================== 51 | 52 | source("code/analysis_mr_sbp_ad.R") 53 | 54 | # Generate supplementary figure 2 ============================================= 55 | 56 | source("code/output_mr_exp_sbp.R") 57 | 58 | # Generate main figure and supplementary figure 3 ============================= 59 | 60 | source("code/output_mr_sbp_ad.R") 61 | 62 | # Generate supplementary tables =============================================== 63 | 64 | source("code/supplementary_tables.R") 65 | 66 | # Run sensitivity analyses ==================================================== 67 | 68 | source("code/sensitivity_common_data.R") 69 | source("code/sensitivity_gill.R") 70 | source("code/sensitivity_instrument_overlap.R") 71 | -------------------------------------------------------------------------------- /sensitivity_instrument_overlap.R: -------------------------------------------------------------------------------- 1 | # LOAD DATA =================================================================== 2 | 3 | df <- data.frame(read_csv("data/mr_sbp_ad.csv")) 4 | df <- df[df$level %in% c("Drug","Overall") & df$methodtype=="main",c("leveli","snps.mr")] 5 | df <- df %>% 6 | mutate(snp = strsplit(as.character(snps.mr), ";")) %>% 7 | unnest(snp) 8 | 9 | larsson <- read.xlsx("data/larsson.xlsx",sheetName = "Sheet1", 10 | stringsAsFactors=FALSE) 11 | 12 | larsson$snp <- gsub(" ","",larsson$snp) 13 | 14 | ostergaard <- read.xlsx("data/ostergaard.xlsx",sheetName = "Sheet1", 15 | stringsAsFactors=FALSE) 16 | 17 | gill <- read.xlsx("data/gill.xlsx",sheetName = "Sheet1", 18 | stringsAsFactors=FALSE) 19 | 20 | # FIND SNP PROXIES IN OTHER STUDIES =========================================== 21 | 22 | df$snps.mr <- NULL 23 | df$snp.match <- NA 24 | df$source.match <- NA 25 | df$rsq <- NA 26 | df$error <- FALSE 27 | 28 | other_studies <- data.frame(snp = c(larsson$snp,ostergaard$snp,gill$SNP), 29 | source = c(rep("Larsson",length(larsson$snp)), 30 | rep("Ostergaard",length(ostergaard$snp)), 31 | rep("Gill",length(gill$SNP))), 32 | stringsAsFactors = FALSE) 33 | 34 | for (i in c(1:nrow(df))) { 35 | 36 | d <- tryCatch(get_proxies(query = df$snp[i]), error=function(e) NULL) 37 | d <- unique(d[,c("ID","R.squared")]) 38 | 39 | if (is.null(d)) { 40 | df$error[i] <- TRUE 41 | } else { 42 | df$snp.match[i] <- paste0(d[d$ID %in% other_studies$snp,]$ID, collapse = ";") 43 | df$source.match[i] <- paste0(other_studies[other_studies$snp %in% (d[d$ID %in% other_studies$snp,]$ID),2], collapse = ";") 44 | df$rsq[i] <- paste0(sprintf("%.3f",(d[d$ID %in% other_studies$snp,]$R.squared)), collapse = ";") 45 | } 46 | 47 | } 48 | 49 | write.csv(df,file="output/instrument_overlap.csv",row.names = FALSE,na="") 50 | 51 | df$error <- NULL 52 | df <- df[!is.na(df$snp.match) & df$snp.match!="",] 53 | 54 | df <- df %>% 55 | mutate(snp.match = strsplit(as.character(snp.match), ";"), 56 | source.match = strsplit(as.character(source.match), ";"), 57 | rsq = strsplit(as.character(rsq), ";")) %>% 58 | unnest(snp.match,source.match,rsq) 59 | 60 | write.xlsx(data.frame(df), file="output/Supplementary_Tables_AntihypertensivesMR.xlsx", 61 | sheetName="ST6",append=TRUE, row.names = FALSE, showNA = FALSE) 62 | -------------------------------------------------------------------------------- /clean_bnf.R: -------------------------------------------------------------------------------- 1 | # Required libraries: readxl,data.table,tidyverse 2 | 3 | clean_bnf <- function() { 4 | 5 | # Load BNF data =============================================================== 6 | 7 | df <- read_excel("data/Exposures.xlsx", sheet = "IncludedExposures") 8 | 9 | # Restirct to antihypertensives =============================================== 10 | 11 | df <- df[df$Exposure=="Hypertension Drugs",] 12 | 13 | # Format dataframe ============================================================ 14 | 15 | df <- df[,c("Sub-class","Drug Substance Name")] 16 | colnames(df) <- c("drug","substance") 17 | 18 | # Remove polypharmacy medines ================================================= 19 | 20 | df <- df[!grepl("AND",df$drug,ignore.case = FALSE),] 21 | 22 | # Tidy drug substance information ============================================= 23 | 24 | df$drug <- tolower(df$drug) 25 | df$substance <- tolower(df$substance) 26 | df <- df[!is.na(df$substance),] 27 | df <- df[!grepl("/",df$substance),] 28 | 29 | df[df$drug=="vasodilator antihypertensive drugs" & 30 | df$substance=="sodium nitroprusside dihydrate",]$substance <- "nitroprusside" 31 | 32 | df$substance <- sub('(^\\w+)\\s.+','\\1',df$substance) 33 | 34 | 35 | df[df$drug=="thiazides and related diuretics" & 36 | df$substance=="potassium",]$substance <- "potassium chloride" 37 | 38 | 39 | df <- unique(df) 40 | 41 | # Format drug names =========================================================== 42 | 43 | df$drug <- ifelse(df$drug=="beta-adrenoceptor blocking drugs", 44 | "Beta-adrenoceptor blockers",df$drug) 45 | 46 | df$drug <- ifelse(df$drug=="renin inhibitors", 47 | "Renin inhibitors",df$drug) 48 | 49 | df$drug <- ifelse(df$drug=="vasodilator antihypertensive drugs", 50 | "Vasodilator antihypertensives",df$drug) 51 | 52 | df$drug <- ifelse(df$drug=="potassium-sparing diuretics and aldosterone antagonists", 53 | "PSDs and aldosterone antagonists",df$drug) 54 | 55 | df$drug <- ifelse(df$drug=="calcium-channel blockers", 56 | "Calcium channel blockers",df$drug) 57 | 58 | df$drug <- ifelse(df$drug=="centrally acting antihypertensive drugs", 59 | "Centrally acting antihypertensives",df$drug) 60 | 61 | df$drug <- ifelse(df$drug=="thiazides and related diuretics", 62 | "Thiazides and related diuretics",df$drug) 63 | 64 | df$drug <- ifelse(df$drug=="loop diuretics", 65 | "Loop diuretics",df$drug) 66 | 67 | df$drug <- ifelse(df$drug=="angiotensin-ii receptor antagonists", 68 | "Angiotensin-II receptor antagonists",df$drug) 69 | 70 | df$drug <- ifelse(df$drug=="angiotensin-converting enzyme inhibitors", 71 | "Angiotensin converting enzyme inhibitors",df$drug) 72 | 73 | df$drug <- ifelse(df$drug=="alpha-adrenoceptor blocking drugs", 74 | "Alpha-adrenoceptor blockers",df$drug) 75 | 76 | df$drug <- ifelse(df$drug=="adrenergic neurone blocking drugs", 77 | "Adrenergic neurone blockers",df$drug) 78 | 79 | return(df) 80 | 81 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Repurposing antihypertensive drugs for the prevention of Alzheimer’s disease: a Mendelian Randomization study 2 | 3 | [![DOI](https://zenodo.org/badge/161325369.svg)](https://zenodo.org/badge/latestdoi/161325369) 4 | 5 | This respository contains the code to reproduce the analysis from the following paper: 6 | 7 | Venexia M Walker, Patrick G Kehoe, Richard M Martin, Neil M Davies, Repurposing antihypertensive drugs for the prevention of Alzheimer’s disease: a Mendelian randomization study, International Journal of Epidemiology, , dyz155, https://doi.org/10.1093/ije/dyz155 8 | 9 | ## Abstract 10 | 11 | Background: Evidence concerning the potential repurposing of antihypertensives for Alzheimer’s disease prevention is inconclusive. We used Mendelian randomization, which can be more robust to confounding by indication and patient characteristics, to investigate the effects of lowering systolic blood pressure (SBP), via different antihypertensive drug classes, on Alzheimer’s disease. 12 | 13 | Methods: We used summary statistics from genome wide association studies of SBP (from UK Biobank) and Alzheimer’s disease (from the International Genomics of Alzheimer's Project) in a two-sample Mendelian randomization analysis. We identified single nucleotide polymorphisms (SNPs) that mimic the action of antihypertensive targets and estimated the effect of lowering SBP, via antihypertensive drug classes, on Alzheimer’s disease. We also report the effect of lowering SBP on Alzheimer’s disease by combining all drug targets and without consideration of the associated drugs. 14 | 15 | Results: There was limited evidence that lowering SBP, via antihypertensive drug classes, affected Alzheimer’s disease risk. For example, calcium channel blockers had an odds ratio (OR) per 10mmHg lower SBP of 1.53 (95% confidence interval (CI): 0.94 to 2.49; p=0.09; SNPs=17). We also found limited evidence for an effect of lowering SBP on Alzheimer’s disease when combining all drug targets (OR per 10mmHg lower SBP: 1.14; 95%CI: 0.83 to 1.56; p=0.41; SNPs=59) and without consideration of the associated drug targets (OR per 10mmHg lower SBP: 1.04; 95%CI: 0.95 to 1.13; p=0.45; SNPs=153). 16 | 17 | Conclusions: Lowering SBP itself is unlikely to affect risk of developing Alzheimer’s disease. Consequently, if specific antihypertensive drug classes do affect risk of Alzheimer’s disease, they are unlikely to do so via SBP. 18 | 19 | 20 | ## Using this code 21 | 22 | To run this code, set your working directly in the file 'config.R' and run this file. All other files are called when required from this file. If you would like any more information, please contact venexia.walker@bristol.ac.uk. 23 | 24 | ## Availability of data 25 | 26 | The data used in this project are publicly available and have been obtained from the following sources: 27 | 28 | MR-Base - http://mrbase.org 29 | 30 | DrugBank - https://www.drugbank.ca/releases/latest 31 | 32 | GTEx - https://gtexportal.org/home/datasets 33 | 34 | Neale lab systolic blood pressure GWAS - http://www.nealelab.is/uk-biobank/ 35 | 36 | Larsson et al instruments - https://www.bmj.com/content/359/bmj.j5375 37 | 38 | Ostergaard et al instruments - https://journals.plos.org/plosmedicine/article?id=10.1371/journal.pmed.1001841 39 | 40 | Gill et al instruments - https://www.biorxiv.org/content/early/2018/11/05/460543 41 | 42 | ## Funding statement 43 | 44 | This work was supported by the Perros Trust and the Integrative Epidemiology Unit. The Integrative Epidemiology Unit is supported by the Medical Research Council and the University of Bristol [grant number MC_UU_00011/1, MC_UU_00011/3]. 45 | -------------------------------------------------------------------------------- /supplementary_tables.R: -------------------------------------------------------------------------------- 1 | # Supplementary Table 2 ======================================================= 2 | 3 | input_exp <- fread("data/input_exp.csv", 4 | stringsAsFactors = FALSE, 5 | data.table = FALSE) 6 | 7 | input_exp <- input_exp[,c("gene","tissue","keep")] 8 | 9 | colnames(input_exp) <- c("gene","tissue","ind.ins") 10 | 11 | mr_exp_sbp <- fread("data/mr_exp_sbp.csv", 12 | stringsAsFactors = FALSE, 13 | data.table = FALSE) 14 | 15 | st2 <- merge(input_exp,mr_exp_sbp,all.x = TRUE, by = c("gene","tissue")) 16 | 17 | st2$ind.mr <- ifelse(!is.na(st2$beta.mr),TRUE,FALSE) 18 | 19 | st2$ind.sbpev <- ifelse(!is.na(st2$beta.mr) & sign(st2$lci.mr)==sign(st2$uci.mr),TRUE,FALSE) 20 | 21 | st2 <- st2[,c(1:2,11,19:20,24:25,21:23,6,9:10,3,26:27)] 22 | 23 | colnames(st2) <- c(colnames(st2)[1:2],"SNP",colnames(st2)[4:7], 24 | "beta.expression","se.expression","pval.expression", 25 | colnames(st2)[11:16]) 26 | 27 | write.xlsx(data.frame(st2), file="output/Supplementary_Tables_AntihypertensivesMR.xlsx", 28 | sheetName="ST2",append=TRUE, row.names = FALSE, showNA = FALSE) 29 | 30 | # Supplementary Table 3 ======================================================= 31 | 32 | input_sbp <- fread("data/input_sbp.csv", 33 | stringsAsFactors = FALSE, 34 | data.table = FALSE) 35 | 36 | input_sbp <- input_sbp[,c("drug","gene","SNP")] 37 | 38 | st3 <- suppressWarnings(extract_outcome_data(input_sbp$SNP, 39 | c('UKB-a:360'), 40 | proxies = FALSE)) 41 | 42 | st3 <- st3[,c("SNP","beta.outcome","se.outcome","pval.outcome","eaf.outcome","effect_allele.outcome","other_allele.outcome")] 43 | colnames(st3) <- c("SNP","beta","se","pvalue","eaf","effect_allele","other_allele") 44 | st3$unit <- "sd" 45 | 46 | st3 <- merge(input_sbp,st3, by=c("SNP")) 47 | 48 | ensembl <- fread("data/ensembl_output.txt", 49 | stringsAsFactors = FALSE, 50 | data.table = FALSE) 51 | 52 | ensembl <- ensembl[,c("#Uploaded_variation","Allele","AF")] 53 | colnames(ensembl) <- c("SNP","effect_allele","eaf_1000G") 54 | ensembl <- unique(ensembl) 55 | 56 | st3 <- merge(ensembl,st3, by=c("SNP","effect_allele")) 57 | 58 | write.xlsx(data.frame(st3), file="output/Supplementary_Tables_AntihypertensivesMR.xlsx", 59 | sheetName="ST3",append=TRUE, row.names = FALSE, showNA = FALSE) 60 | 61 | # Supplementary Table 4 ======================================================= 62 | 63 | mr_sbp_ad <- fread("data/mr_sbp_ad.csv", 64 | stringsAsFactors = FALSE, 65 | data.table = FALSE) 66 | 67 | tmp1 <- mr_sbp_ad[!is.na(mr_sbp_ad$beta.mr), 68 | c("leveli","methodtype","beta.mr","lci.mr","uci.mr","se.mr","pval.mr")] 69 | 70 | tmp1 <- reshape(tmp1, idvar = "leveli", timevar = "methodtype", direction = "wide") 71 | 72 | tmp2 <- mr_sbp_ad[mr_sbp_ad$methodtype=="main",c(1:3,9,13:20)] 73 | 74 | st4 <- merge(tmp2,tmp1,all.x = TRUE) 75 | 76 | st4 <- st4[,c(12,1,5,4,3,2,6:11,13:22)] 77 | 78 | write.xlsx(data.frame(st4), file="output/Supplementary_Tables_AntihypertensivesMR.xlsx", 79 | sheetName="ST4",append=TRUE, row.names = FALSE, showNA = FALSE) 80 | 81 | # Supplementary Table 5 ======================================================= 82 | 83 | st5 <- unique(mr_sbp_ad[!is.na(mr_sbp_ad$egger_intercept) & mr_sbp_ad$nsnp>=10, 84 | c("leveli","egger_intercept","egger_se","egger_pval","nsnp")]) 85 | 86 | colnames(st5) <- c("analysis",colnames(st4)[2:5]) 87 | 88 | write.xlsx(data.frame(st5), file="output/Supplementary_Tables_AntihypertensivesMR.xlsx", 89 | sheetName="ST5",append=TRUE, row.names = FALSE, showNA = FALSE) 90 | -------------------------------------------------------------------------------- /analysis_mr_exp_sbp.R: -------------------------------------------------------------------------------- 1 | # List drug targets =========================================================== 2 | 3 | drug_targets <- fread("data/drug_targets.csv", 4 | stringsAsFactors = FALSE, 5 | data.table = FALSE) 6 | 7 | # Identify best SNPs for targets ============================================== 8 | 9 | gtex_path <- "data/gtex/GTEx_Analysis_v7_eQTL/" 10 | gtex_data <- ".v7.egenes.txt" 11 | tissues <- list.files(path = gtex_path,pattern = paste0("*",gtex_data)) 12 | 13 | input_exp <- data.frame(gene = rep(unique(drug_targets$gene),each = length(tissues)), 14 | tissue = rep(tissues,times = length(unique(drug_targets$gene))), 15 | stringsAsFactors = FALSE) 16 | 17 | tmp_input_exp <- NULL 18 | 19 | for (i in tissues) { 20 | 21 | tmp <- suppressWarnings(fread(paste0(gtex_path,i), 22 | stringsAsFactors = FALSE, 23 | data.table = FALSE)) 24 | 25 | tmp <- tmp[tmp$gene_name %in% unique(drug_targets$gene),] 26 | 27 | tmp$tissue <- gsub(gtex_data,"",i) 28 | 29 | tmp_input_exp <- rbind(tmp_input_exp,tmp) 30 | 31 | } 32 | 33 | # Format data for MR analysis ================================================= 34 | 35 | tmp_input_exp <- tmp_input_exp[,c("slope","ref","alt","gene_name","tissue","rs_id_dbSNP147_GRCh37p13", 36 | "gene_chr","gene_start","pval_nominal","slope_se")] 37 | 38 | colnames(tmp_input_exp) <- c("beta.orig","other_allele.orig","effect_allele.orig","gene","tissue", 39 | "SNP","chr_id","chr_pos","pvalue","se") 40 | 41 | # Merge with full gene-tissue df ============================================== 42 | 43 | input_exp$tissue <- gsub(".v7.egenes.txt","",input_exp$tissue) 44 | input_exp <- merge(input_exp,tmp_input_exp,all.x = TRUE,by = c("gene","tissue")) 45 | 46 | # Make all effects positive =================================================== 47 | 48 | input_exp$beta <- ifelse(sign(input_exp$beta.orig)==1,input_exp$beta.orig,-1*input_exp$beta.orig) 49 | 50 | input_exp$effect_allele <- ifelse(sign(input_exp$beta.orig)==1,input_exp$effect_allele.orig,input_exp$other_allele.orig) 51 | 52 | input_exp$other_allele <- ifelse(sign(input_exp$beta.orig)==1,input_exp$other_allele.orig,input_exp$effect_allele.orig) 53 | 54 | input_exp[,c("beta.orig","other_allele.orig","effect_allele.orig")] <- list(NULL) 55 | 56 | # Remove unsuitable SNPs ====================================================== 57 | 58 | input_exp$keep <- ifelse(!is.na(input_exp$SNP) & input_exp$SNP!="." & nchar(input_exp$effect_allele)==1 & nchar(input_exp$other_allele)==1,TRUE,FALSE) 59 | 60 | # Save MR input =============================================================== 61 | 62 | write.csv(input_exp,file="data/input_exp.csv",row.names = FALSE,na = "") 63 | 64 | # Conduct MR of expression on SBP ============================================= 65 | 66 | input_exp <- input_exp[input_exp$keep==TRUE,] 67 | 68 | mr_express <- NULL 69 | 70 | for (i in 1:nrow(input_exp)) { 71 | print(i) 72 | tmp_input_exp <- input_exp[i,] 73 | tmp_mr_express <- MR(tmp_input_exp,c('UKB-a:360')) 74 | tmp_mr_express$gene <- input_exp[i,]$gene 75 | tmp_mr_express$tissue <- input_exp[i,]$tissue 76 | mr_express <- rbind(mr_express,tmp_mr_express) 77 | } 78 | 79 | mr_express[,c("beta.exposure","se.exposure","pval.exposure")] <- NULL 80 | input_exp <- input_exp[,c("gene","tissue","chr_id","chr_pos","beta","se","pvalue","effect_allele","other_allele")] 81 | colnames(input_exp) <- c("gene","tissue","chr_id","chr_pos","beta.exposure","se.exposure","pval.exposure","effect_allele","other_allele") 82 | mr_express <- merge(mr_express,input_exp,by=c("gene","tissue"),all.x = TRUE) 83 | 84 | # mr_express <- group_MR(df = input_exp, outcome.data = "mrbase", outcome = c('UKB-a:360'), tissue, gene) 85 | # mr_express$index <- NULL 86 | 87 | # Save output ================================================================= 88 | 89 | write.csv(mr_express,file="data/mr_exp_sbp.csv",row.names = FALSE,na = "") -------------------------------------------------------------------------------- /analysis_mr_sbp_ad.R: -------------------------------------------------------------------------------- 1 | # List drug targets =========================================================== 2 | 3 | drug_targets <- fread("data/drug_targets.csv", 4 | stringsAsFactors = FALSE, 5 | data.table = FALSE) 6 | 7 | # List instruments ============================================================ 8 | 9 | mr_express <- fread("data/mr_exp_sbp.csv", 10 | stringsAsFactors = FALSE, 11 | data.table = FALSE) 12 | 13 | mr_express <- mr_express[!is.na(mr_express$beta.mr) & sign(mr_express$lci.mr)==sign(mr_express$uci.mr),c("snps.in","gene")] 14 | 15 | colnames(mr_express) <- c("SNP","gene") 16 | 17 | mr_express <- unique(mr_express) 18 | 19 | # Load SBP data =============================================================== 20 | 21 | input_sbp <- suppressWarnings(extract_outcome_data(mr_express$SNP, 22 | c('UKB-a:360'), 23 | proxies = FALSE)) 24 | 25 | input_sbp <- input_sbp[,c("beta.outcome","other_allele.outcome","effect_allele.outcome", 26 | "SNP","pval.outcome","se.outcome")] 27 | 28 | colnames(input_sbp) <- c("beta.orig","other_allele.orig","effect_allele.orig", 29 | "SNP","pvalue","se") 30 | 31 | input_sbp <- unique(input_sbp) 32 | 33 | # Make all effects positive --------------------------------------------------- 34 | 35 | input_sbp$beta <- ifelse(sign(input_sbp$beta.orig)==1,input_sbp$beta.orig,-1*input_sbp$beta.orig) 36 | 37 | input_sbp$effect_allele <- ifelse(sign(input_sbp$beta.orig)==1,input_sbp$effect_allele.orig,input_sbp$other_allele.orig) 38 | 39 | input_sbp$other_allele <- ifelse(sign(input_sbp$beta.orig)==1,input_sbp$other_allele.orig,input_sbp$effect_allele.orig) 40 | 41 | input_sbp[,c("beta.orig","other_allele.orig","effect_allele.orig")] <- list(NULL) 42 | 43 | # Merge with drug targets ===================================================== 44 | 45 | input_sbp <- merge(input_sbp,mr_express,by = c("SNP")) 46 | input_sbp <- merge(input_sbp,drug_targets,by = c("gene")) 47 | 48 | # Save ======================================================================== 49 | 50 | input_sbp <- input_sbp[,c(8,1:2,6:7,5,4,3)] 51 | input_sbp$unit <- "sd" 52 | write.csv(input_sbp,file="data/input_sbp.csv",row.names = FALSE,na = "") 53 | 54 | # Target analysis ============================================================= 55 | 56 | mr_target <- group_MR(df = input_sbp, outcome.data = "mrbase", outcome = c(297), gene) 57 | mr_target$level <- "Target" 58 | names(mr_target)[names(mr_target)=="gene"] <- "leveli" 59 | 60 | # Drug class analysis ========================================================= 61 | 62 | mr_drug <- group_MR(df = input_sbp, outcome.data = "mrbase", outcome = c(297), drug) 63 | mr_drug$level <- "Drug" 64 | names(mr_drug)[names(mr_drug)=="drug"] <- "leveli" 65 | 66 | # Combined target analysis ==================================================== 67 | 68 | input_sbp$grp <- "Combined" 69 | mr_overall <- group_MR(df = input_sbp, outcome.data = "mrbase", outcome = c(297), grp) 70 | mr_overall$level <- "Combined" 71 | names(mr_overall)[names(mr_overall)=="grp"] <- "leveli" 72 | 73 | # Overall analysis ============================================================ 74 | 75 | input_ukb <- extract_instruments(outcomes='UKB-a:360') 76 | 77 | input_ukb <- input_ukb[,c("SNP","beta.exposure","se.exposure","samplesize.exposure","pval.exposure", 78 | "eaf.exposure","effect_allele.exposure","other_allele.exposure")] 79 | 80 | colnames(input_ukb) <- c("SNP","beta","se","samplesize","pval", 81 | "eaf","effect_allele","other_allele") 82 | 83 | write.csv(input_ukb,file="data/input_ukb.csv",row.names = FALSE) 84 | 85 | input_ukb$grp <- "Overall" 86 | 87 | mr_ukb <- group_MR(df = input_ukb, outcome.data = "mrbase", outcome = c(297), grp) 88 | 89 | mr_ukb$level <- "Overall" 90 | 91 | names(mr_ukb)[names(mr_ukb)=="grp"] <- "leveli" 92 | 93 | # Make results file =========================================================== 94 | 95 | results <- rbind(mr_overall,mr_drug,mr_target,mr_ukb) 96 | 97 | # Format results data ========================================================= 98 | # Divide by sd of SBP in UK Biobank (19.268) and multiply by 10 to get effect per 10mmHg 99 | 100 | results$index <- NULL 101 | results$or <- 1/exp(results$beta.mr*(10/19.268)) 102 | results$uci <- 1/exp(results$lci.mr*(10/19.268)) 103 | results$lci <- 1/exp(results$uci.mr*(10/19.268)) 104 | results$methodtype <- ifelse(results$method=="MR Egger" & !is.na(results$method),"sensitivity","main") 105 | 106 | # Save results ================================================================ 107 | 108 | write.csv(results,file="data/mr_sbp_ad.csv",row.names = FALSE,na = "") -------------------------------------------------------------------------------- /func_MR.R: -------------------------------------------------------------------------------- 1 | # Required libraries: TwoSampleMR, tidyverse, furrr 2 | 3 | MR <- function(input,outcome,wait=FALSE) { 4 | 5 | # System waiting for parallel processing ==================================== 6 | 7 | if (wait) { 8 | wait_time <- runif(1, 0.5, 2) 9 | Sys.sleep(wait_time) 10 | } 11 | 12 | # Clear previous results ==================================================== 13 | 14 | exp <- NULL 15 | out <- NULL 16 | dat <- NULL 17 | res <- NULL 18 | ptest <- NULL 19 | output <- NULL 20 | 21 | # Format exposure data ====================================================== 22 | 23 | exp <- suppressWarnings(format_data(input, type="exposure")) 24 | 25 | # Clump data if required ==================================================== 26 | 27 | if (nrow(exp)>1) { 28 | 29 | exp <- clump_data(exp) 30 | 31 | } 32 | 33 | # Extract outcome data ====================================================== 34 | 35 | out <- suppressWarnings(extract_outcome_data(exp$SNP, 36 | outcome, 37 | proxies = 1, 38 | rsq = 0.8, 39 | align_alleles = 1, 40 | palindromes = 1, 41 | maf_threshold = 0.3)) 42 | 43 | # Harmonise exposure and outcome data ======================================= 44 | 45 | if (!is.null(out)) { 46 | 47 | dat <- harmonise_data(exposure_dat = exp, 48 | outcome_dat = out) 49 | 50 | if(!is.null(dat)) { 51 | 52 | # Perform MR ================================================================ 53 | 54 | if (nrow(dat)==1 && dat$mr_keep==TRUE) { 55 | 56 | res <- mr(dat, method_list = c("mr_wald_ratio")) 57 | 58 | } 59 | 60 | if (nrow(dat)>1) { 61 | 62 | res <- mr(dat, method_list = c("mr_ivw","mr_egger_regression")) 63 | ptest <- mr_pleiotropy_test(dat) 64 | colnames(ptest) <- c("id.exposure","id.outcome","outcome","exposure", 65 | "egger_intercept","egger_se","egger_pval") 66 | res <- merge(res,ptest) 67 | 68 | } 69 | } 70 | } 71 | 72 | # Save results ============================================================== 73 | 74 | if (!is.null(res)) { 75 | if (nrow(res)>0 & is.null(ptest)) { 76 | output <- res 77 | output$snps.mr <- paste(dat$SNP,collapse=";") 78 | output$beta.exposure <- paste(dat$beta.exposure,collapse=";") 79 | output$se.exposure <- paste(dat$se.exposure,collapse=";") 80 | output$pval.exposure <- paste(dat$pval.exposure,collapse=";") 81 | output$beta.outcome <- paste(dat$beta.outcome,collapse=";") 82 | output$se.outcome <- paste(dat$se.outcome,collapse=";") 83 | output$pval.outcome <- paste(dat$pval.outcome,collapse=";") 84 | output$egger_intercept <- NA 85 | output$egger_se <- NA 86 | output$egger_pval <- NA 87 | } 88 | else if (nrow(res)>0 & !is.null(ptest)) { 89 | output <- res 90 | output$snps.mr <- paste(dat$SNP,collapse=";") 91 | output$beta.exposure <- paste(dat$beta.exposure,collapse=";") 92 | output$se.exposure <- paste(dat$se.exposure,collapse=";") 93 | output$pval.exposure <- paste(dat$pval.exposure,collapse=";") 94 | output$beta.outcome <- paste(dat$beta.outcome,collapse=";") 95 | output$se.outcome <- paste(dat$se.outcome,collapse=";") 96 | output$pval.outcome <- paste(dat$pval.outcome,collapse=";") 97 | } 98 | else { 99 | output <- setNames(data.frame(matrix(ncol = 20, nrow = 1)), 100 | c("id.exposure","id.outcome","outcome","exposure", 101 | "method","nsnp","b","se","pval","snps.mr", 102 | "egger_intercept","egger_se","egger_pval","snps.in", 103 | "beta.exposure","se.exposure","pval.exposure", 104 | "beta.outcome","se.outcome","pval.outcome")) 105 | } 106 | } else { 107 | output <- setNames(data.frame(matrix(ncol = 20, nrow = 1)), 108 | c("id.exposure","id.outcome","outcome","exposure", 109 | "method","nsnp","b","se","pval","snps.mr", 110 | "egger_intercept","egger_se","egger_pval","snps.in", 111 | "beta.exposure","se.exposure","pval.exposure", 112 | "beta.outcome","se.outcome","pval.outcome")) 113 | } 114 | 115 | output$snps.in <- paste(input$SNP,collapse=";") 116 | 117 | output$lci.mr <- output$b - qnorm(0.975)*output$se 118 | output$uci.mr <- output$b + qnorm(0.975)*output$se 119 | 120 | output <- output[,c("method","nsnp","b","lci.mr","uci.mr","se","pval", 121 | "snps.mr","egger_intercept","egger_se","egger_pval","snps.in", 122 | "beta.exposure","se.exposure","pval.exposure", 123 | "beta.outcome","se.outcome","pval.outcome")] 124 | 125 | colnames(output) <- c("method","nsnp","beta.mr","lci.mr","uci.mr","se.mr","pval.mr", 126 | "snps.mr","egger_intercept","egger_se","egger_pval","snps.in", 127 | "beta.exposure","se.exposure","pval.exposure", 128 | "beta.outcome","se.outcome","pval.outcome") 129 | 130 | return(output) 131 | 132 | } 133 | -------------------------------------------------------------------------------- /sensitivity_gill.R: -------------------------------------------------------------------------------- 1 | # Beta-adrenoceptor blockers from Gill et al ================================== 2 | 3 | gill <- read.xlsx("data/gill.xlsx",sheetName = "Sheet1", 4 | stringsAsFactors=FALSE) 5 | 6 | input_gill <- suppressWarnings(extract_outcome_data(gill$SNP, 7 | c('UKB-a:360'), 8 | proxies = FALSE)) 9 | 10 | input_gill <- input_gill[,c("SNP","beta.outcome","se.outcome","samplesize.outcome", 11 | "pval.outcome","eaf.outcome","effect_allele.outcome", 12 | "other_allele.outcome")] 13 | 14 | input_gill <- merge(input_gill,gill[,c("SNP","Drug")],all.x=TRUE,by=c("SNP")) 15 | 16 | colnames(input_gill) <- c("SNP","beta","se","samplesize","pval", 17 | "eaf","effect_allele","other_allele","drug") 18 | 19 | write.csv(input_gill,file="data/input_gill.csv",row.names = FALSE) 20 | 21 | mr_gill <- group_MR(df = input_gill[input_gill$SNP!="rs1801253",], outcome.data = "mrbase", outcome = c(297), drug) 22 | 23 | mr_gill$index <- NULL 24 | 25 | mr_gill$study <- "Gill et al" 26 | mr_gill$leveli <- mr_gill$drug 27 | 28 | mr_gill <- mr_gill[,c("method","beta.mr","lci.mr","uci.mr","pval.mr","study", 29 | "leveli","nsnp")] 30 | 31 | # WALKER ====================================================================== 32 | 33 | mr_walker <- read.csv("data/mr_sbp_ad.csv") 34 | 35 | mr_walker$study <- "Present study" 36 | 37 | mr_walker <- mr_walker[mr_walker$leveli %in% c("Beta-adrenoceptor blockers","Calcium channel blockers"), 38 | c("method","beta.mr","lci.mr","uci.mr","pval.mr","study","leveli","nsnp")] 39 | 40 | # Combine all studies ========================================================= 41 | 42 | df <- rbind(mr_gill,mr_walker) 43 | 44 | # Create OR labels ============================================================ 45 | 46 | df$or <- 1/exp(df$beta.mr*(10/19.268)) 47 | df$uci <- 1/exp(df$lci.mr*(10/19.268)) 48 | df$lci <- 1/exp(df$uci.mr*(10/19.268)) 49 | 50 | df$orlab <- paste0("OR: ",sprintf("%.2f",df$or), 51 | " (95% CI: ", sprintf("%.2f",df$lci), 52 | " to ", sprintf("%.2f",df$uci), 53 | "); p = ", sprintf("%.2f",df$pval.mr)) 54 | 55 | df$orlab <- ifelse(df$pval.mr<0.01, 56 | paste0("OR: ",sprintf("%.2f",df$or), 57 | " (95% CI: ", sprintf("%.2f",df$lci), 58 | " to ", sprintf("%.2f",df$uci), 59 | "); p = ", sprintf("%.3f",df$pval.mr)), 60 | df$orlab) 61 | 62 | df$orlab <- ifelse(df$pval.mr<0.001, 63 | paste0("OR: ",sprintf("%.2f",df$or), 64 | " (95% CI: ", sprintf("%.2f",df$lci), 65 | " to ", sprintf("%.2f",df$uci), 66 | "); p < 0.001"), 67 | df$orlab) 68 | 69 | df$orlab <- ifelse(df$pval.mr>0.99, 70 | paste0("OR: ",sprintf("%.2f",df$or), 71 | " (95% CI: ", sprintf("%.2f",df$lci), 72 | " to ", sprintf("%.2f",df$uci), 73 | "); p > 0.99"), 74 | df$orlab) 75 | 76 | df$lab <- paste0(df$study,": ",df$leveli) 77 | 78 | # Map main and sensitivity analyses to same label ============================= 79 | 80 | df$methodtype <- ifelse(df$method=="MR Egger","sensitivity","main") 81 | tmp <- df[,c("lab","methodtype","orlab")] 82 | tmp <- spread(tmp, methodtype, orlab) 83 | tmp$sensitivity <- ifelse(is.na(tmp$sensitivity),"",tmp$sensitivity) 84 | df <- merge(df,tmp, by = c("lab")) 85 | 86 | # Define study labels ========================================================= 87 | 88 | df$studylab <- paste0(df$study," (# SNPs = ",df$nsnp, 89 | ")\n",df$main, 90 | "\n",df$sensitivity) 91 | 92 | df$studylab <- factor(df$studylab) 93 | df$studylab <- factor(df$studylab,levels(df$studylab)[c(3,1,4,2)]) 94 | 95 | # Refine method label ========================================================= 96 | 97 | df$methodtype <- factor(df$methodtype) 98 | df$methodtype <- fct_rev(factor(df$methodtype)) 99 | 100 | # Plot sensitivity results ==================================================== 101 | 102 | ggplot(df, aes(x = studylab,y = or,group = methodtype, shape = methodtype)) + 103 | geom_point(stat = "identity", position = position_dodge(width = 0.5)) + 104 | geom_linerange(aes(ymin = lci, ymax = uci), position = position_dodge(width = 0.5)) + 105 | geom_hline(yintercept=1, linetype = 2) + 106 | scale_shape_manual(name ="Method", 107 | breaks=c("main", "sensitivity"), 108 | labels=c("Wald ratio / IVW", "MR Egger"), 109 | values=c(17,15), 110 | guide = guide_legend(nrow = 1)) + 111 | scale_x_discrete(name = "") + 112 | scale_y_log10(name = "OR and 95% CI for developing Alzheimer's disease for a 10mmHg\ndecrease in systolic blood pressure (presented on log scale)", 113 | limits = c(min(df$lci),max(df$uci)), breaks = c(0.015625,0.03125,0.0625,0.125,0.25,0.5,1,2,4,8,16,32,64)) + 114 | theme_minimal() + 115 | theme(panel.grid.major.y=element_blank(), 116 | panel.grid.minor = element_blank(), 117 | axis.text=element_text(size=8), 118 | text=element_text(size=8), 119 | legend.position="bottom") + 120 | coord_flip() + 121 | facet_wrap(~leveli, ncol = 1, scales = "free_y") 122 | 123 | ggsave("output/mr_gill.jpeg", height = 6, width = 12, unit = "cm", dpi = 600, scale = 1.75) 124 | 125 | -------------------------------------------------------------------------------- /output_mr_exp_sbp.R: -------------------------------------------------------------------------------- 1 | # LOAD DATA =================================================================== 2 | 3 | drug_targets <- fread("data/drug_targets.csv", 4 | stringsAsFactors = FALSE, 5 | data.table = FALSE) 6 | 7 | mr_exp_sbp <- read_csv("data/mr_exp_sbp.csv") 8 | 9 | # LABEL GTEX TISSUES =========================================================== 10 | 11 | gtexlab <- data.frame(rbind(c("Adipose_Subcutaneous","Adipose - Subcutaneous"), 12 | c("Adipose_Visceral_Omentum","Adipose - Visceral (Omentum)"), 13 | c("Adrenal_Gland","Adrenal Gland"), 14 | c("Artery_Aorta","Artery - Aorta"), 15 | c("Artery_Coronary","Artery - Coronary"), 16 | c("Artery_Tibial","Artery - Tibial"), 17 | c("Brain_Amygdala","Brain - Amygdala"), 18 | c("Brain_Anterior_cingulate_cortex_BA24","Brain - Anterior cingulate cortex (BA24)"), 19 | c("Brain_Caudate_basal_ganglia","Brain - Caudate (basal ganglia)"), 20 | c("Brain_Cerebellar_Hemisphere","Brain - Cerebellar Hemisphere"), 21 | c("Brain_Cerebellum","Brain - Cerebellum"), 22 | c("Brain_Cortex","Brain - Cortex"), 23 | c("Brain_Frontal_Cortex_BA9","Brain - Frontal Cortex (BA9)"), 24 | c("Brain_Hippocampus","Brain - Hippocampus"), 25 | c("Brain_Hypothalamus","Brain - Hypothalamus"), 26 | c("Brain_Nucleus_accumbens_basal_ganglia","Brain - Nucleus accumbens (basal ganglia)"), 27 | c("Brain_Putamen_basal_ganglia","Brain - Putamen (basal ganglia)"), 28 | c("Brain_Spinal_cord_cervical_c-1","Brain - Spinal cord (cervical c-1)"), 29 | c("Brain_Substantia_nigra","Brain - Substantia nigra"), 30 | c("Breast_Mammary_Tissue","Breast - Mammary Tissue"), 31 | c("Cells_EBV-transformed_lymphocytes","Cells - EBV-transformed lymphocytes"), 32 | c("Cells_Transformed_fibroblasts","Cells - Transformed fibroblasts"), 33 | c("Colon_Sigmoid","Colon - Sigmoid"), 34 | c("Colon_Transverse","Colon - Transverse"), 35 | c("Esophagus_Gastroesophageal_Junction","Esophagus - Gastroesophageal Junction"), 36 | c("Esophagus_Mucosa","Esophagus - Mucosa"), 37 | c("Esophagus_Muscularis","Esophagus - Muscularis"), 38 | c("Heart_Atrial_Appendage","Heart - Atrial Appendage"), 39 | c("Heart_Left_Ventricle","Heart - Left Ventricle"), 40 | c("Liver","Liver"), 41 | c("Lung","Lung"), 42 | c("Minor_Salivary_Gland","Minor Salivary Gland"), 43 | c("Muscle_Skeletal","Muscle - Skeletal"), 44 | c("Nerve_Tibial","Nerve - Tibial"), 45 | c("Ovary","Ovary"), 46 | c("Pancreas","Pancreas"), 47 | c("Pituitary","Pituitary"), 48 | c("Prostate","Prostate"), 49 | c("Skin_Not_Sun_Exposed_Suprapubic","Skin - Not Sun Exposed (Suprapubic)"), 50 | c("Skin_Sun_Exposed_Lower_leg","Skin - Sun Exposed (Lower leg)"), 51 | c("Small_Intestine_Terminal_Ileum","Small Intestine - Terminal Ileum"), 52 | c("Spleen","Spleen"), 53 | c("Stomach","Stomach"), 54 | c("Testis","Testis"), 55 | c("Thyroid","Thyroid"), 56 | c("Uterus","Uterus"), 57 | c("Vagina","Vagina"), 58 | c("Whole_Blood","Whole Blood"))) 59 | 60 | colnames(gtexlab) <- c("tissue","tissue_di") 61 | 62 | mr_exp_sbp <- merge(mr_exp_sbp,gtexlab) 63 | 64 | # FORMAT DATA ================================================================= 65 | 66 | mr_exp_sbp <- merge(mr_exp_sbp,drug_targets) 67 | mr_exp_sbp$ex_null <- ifelse(mr_exp_sbp$lci.mr<0 & mr_exp_sbp$uci.mr>0,NA,1) 68 | 69 | # MARK GENES WITHOUT EVIDENCE FOR AN EFFECT ON SBP ============================ 70 | 71 | mr_exp_sbp$proceed <- ifelse(!is.na(mr_exp_sbp$beta.mr) & sign(mr_exp_sbp$lci.mr)==sign(mr_exp_sbp$uci.mr),1,0) 72 | 73 | tmp <- mr_exp_sbp %>% 74 | group_by(gene) %>% 75 | summarise(include = max(proceed)) %>% 76 | ungroup() 77 | 78 | mr_exp_sbp$gene_di <- ifelse(mr_exp_sbp$gene %in% tmp[tmp$include==0,]$gene, 79 | paste0(mr_exp_sbp$gene,"*"),mr_exp_sbp$gene) 80 | 81 | ggplot(mr_exp_sbp, aes(y = reorder(gene_di, desc(gene_di)), x = tissue_di)) + 82 | labs(y = "Target", x = "Tissue", fill = "Beta\n") + 83 | scale_x_discrete(position = "top") + 84 | scale_y_discrete(position = "right") + 85 | facet_grid(mr_exp_sbp$drug~., scales = "free", space = "free", switch = "both") + 86 | theme_bw() + 87 | theme(panel.grid.major = element_blank(), 88 | axis.text=element_text(size=8), 89 | axis.title=element_text(size=8), 90 | legend.position = "bottom", 91 | legend.text=element_text(size=8), 92 | legend.title=element_text(size=8), 93 | axis.text.x = element_text(angle = 90, hjust = 0), 94 | strip.text.y = element_text(angle = 180, hjust = 1, size=8), 95 | strip.background = element_blank()) + 96 | geom_tile(aes(fill = beta.mr)) + 97 | geom_point(aes(shape = factor(ex_null)), size = 0.5) + 98 | scale_shape_discrete(name = " ", 99 | breaks=c("1", "0"), 100 | labels=c("95% CI excludes null", "Label")) + 101 | scale_fill_distiller(palette = "Spectral", direction = -1, 102 | guide = "colourbar", limits = c(-0.2,0.2), 103 | na.value = NA) 104 | ggsave("output/mr_exp_sbp.jpeg",width = 200, height = 300, unit = "mm", dpi = 600) 105 | -------------------------------------------------------------------------------- /sensitivity_common_data.R: -------------------------------------------------------------------------------- 1 | # LARSSON =========================================================== 2 | 3 | larsson <- read.xlsx("data/larsson.xlsx",sheetName = "Sheet1", 4 | stringsAsFactors=FALSE) 5 | 6 | larsson$snp <- gsub(" ","",larsson$snp) 7 | 8 | input_lar <- suppressWarnings(extract_outcome_data(larsson$snp, 9 | c('UKB-a:360'), 10 | proxies = FALSE)) 11 | 12 | input_lar <- input_lar[,c("SNP","beta.outcome","se.outcome","samplesize.outcome","pval.outcome", 13 | "eaf.outcome","effect_allele.outcome","other_allele.outcome")] 14 | 15 | colnames(input_lar) <- c("SNP","beta","se","samplesize","pval", 16 | "eaf","effect_allele","other_allele") 17 | 18 | write.csv(input_lar,file="data/input_larsson.csv",row.names = FALSE) 19 | 20 | input_lar$study <- "Larsson et al" 21 | 22 | mr_larsson <- group_MR(df = input_lar, outcome.data = "mrbase", outcome = c(297), study) 23 | 24 | mr_larsson$index <- NULL 25 | 26 | # OSTERGAARD ======================================================== 27 | 28 | ostergaard <- read.xlsx("data/ostergaard.xlsx",sheetName = "Sheet1", 29 | stringsAsFactors=FALSE) 30 | 31 | input_ost <- suppressWarnings(extract_outcome_data(ostergaard$snp, 32 | c('UKB-a:360'), 33 | proxies = FALSE)) 34 | 35 | input_ost <- input_ost[,c("SNP","beta.outcome","se.outcome","samplesize.outcome","pval.outcome", 36 | "eaf.outcome","effect_allele.outcome","other_allele.outcome")] 37 | 38 | colnames(input_ost) <- c("SNP","beta","se","samplesize","pval", 39 | "eaf","effect_allele","other_allele") 40 | 41 | write.csv(input_ost,file="data/input_ostergaard.csv",row.names = FALSE) 42 | 43 | input_ost$study <- "Ostergaard et al" 44 | 45 | mr_ostergaard <- group_MR(df = input_ost, outcome.data = "mrbase", outcome = c(297), study) 46 | 47 | mr_ostergaard$index <- NULL 48 | 49 | # WALKER ====================================================================== 50 | 51 | mr_walker <- read.csv("data/mr_sbp_ad.csv",stringsAsFactors = FALSE) 52 | 53 | mr_walker$study <- NA 54 | 55 | mr_walker$study <- ifelse(mr_walker$level=="Overall","Present study: systolic blood pressure",mr_walker$study) 56 | 57 | mr_walker$study <- ifelse(mr_walker$level=="Combined","Present study: antihypertensive drugs",mr_walker$study) 58 | 59 | mr_walker <- mr_walker[mr_walker$level %in% c("Overall","Combined"),colnames(mr_larsson)] 60 | 61 | 62 | # Combine all studies ========================================================= 63 | 64 | df <- rbind(mr_larsson,mr_ostergaard,mr_walker) 65 | 66 | # Create OR labels ============================================================ 67 | 68 | df$or <- 1/exp(df$beta.mr*(10/19.268)) 69 | df$uci <- 1/exp(df$lci.mr*(10/19.268)) 70 | df$lci <- 1/exp(df$uci.mr*(10/19.268)) 71 | 72 | df$orlab <- paste0("OR: ",sprintf("%.2f",df$or), 73 | " (95% CI: ", sprintf("%.2f",df$lci), 74 | " to ", sprintf("%.2f",df$uci), 75 | "); p = ", sprintf("%.2f",df$pval.mr)) 76 | 77 | df$orlab <- ifelse(df$pval.mr<0.01, 78 | paste0("OR: ",sprintf("%.2f",df$or), 79 | " (95% CI: ", sprintf("%.2f",df$lci), 80 | " to ", sprintf("%.2f",df$uci), 81 | "); p = ", sprintf("%.3f",df$pval.mr)), 82 | df$orlab) 83 | 84 | df$orlab <- ifelse(df$pval.mr<0.001, 85 | paste0("OR: ",sprintf("%.2f",df$or), 86 | " (95% CI: ", sprintf("%.2f",df$lci), 87 | " to ", sprintf("%.2f",df$uci), 88 | "); p < 0.001"), 89 | df$orlab) 90 | 91 | df$orlab <- ifelse(df$pval.mr>0.99, 92 | paste0("OR: ",sprintf("%.2f",df$or), 93 | " (95% CI: ", sprintf("%.2f",df$lci), 94 | " to ", sprintf("%.2f",df$uci), 95 | "); p > 0.99"), 96 | df$orlab) 97 | 98 | # Map main and sensitivity analyses to same label ============================= 99 | 100 | df$methodtype <- ifelse(df$method=="MR Egger","sensitivity","main") 101 | tmp <- df[,c("study","methodtype","orlab")] 102 | tmp <- spread(tmp, methodtype, orlab) 103 | tmp$sensitivity <- ifelse(is.na(tmp$sensitivity),"",tmp$sensitivity) 104 | df <- merge(df,tmp, by = c("study")) 105 | 106 | # Define study labels ========================================================= 107 | 108 | df$studylab <- paste0(df$study," (# SNPs = ",df$nsnp, 109 | ")\n",df$main, 110 | "\n",df$sensitivity) 111 | 112 | df$studylab <- factor(df$studylab) 113 | 114 | # Refine method label ========================================================= 115 | 116 | df$methodtype <- factor(df$methodtype) 117 | df$methodtype <- fct_rev(factor(df$methodtype)) 118 | 119 | # Plot sensitivity results ==================================================== 120 | 121 | ggplot(df, aes(x = studylab,y = or,group = methodtype, shape = methodtype)) + 122 | geom_point(stat = "identity", position = position_dodge(width = 0.5)) + 123 | geom_linerange(aes(ymin = lci, ymax = uci), position = position_dodge(width = 0.5)) + 124 | geom_hline(yintercept=1, linetype = 2) + 125 | scale_shape_manual(name ="Method", 126 | breaks=c("main", "sensitivity"), 127 | labels=c("Wald ratio / IVW", "MR Egger"), 128 | values=c(17,15), 129 | guide = guide_legend(nrow = 1)) + 130 | scale_x_discrete(name = "") + 131 | scale_y_log10(name = "OR and 95% CI for developing Alzheimer's disease for a 10mmHg\ndecrease in systolic blood pressure (presented on log scale)", 132 | limits = c(0.5,8), breaks = c(0.5,1,2,4,8)) + 133 | theme_minimal() + 134 | theme(panel.grid.major.y=element_blank(), 135 | panel.grid.minor = element_blank(), 136 | axis.text=element_text(size=8), 137 | text=element_text(size=8), 138 | legend.position="bottom") + 139 | coord_flip() 140 | 141 | ggsave("output/mr_common_data.jpeg", height = 6, width = 12, unit = "cm", dpi = 600, scale = 1.75) 142 | 143 | -------------------------------------------------------------------------------- /output_mr_sbp_ad.R: -------------------------------------------------------------------------------- 1 | # Load drug targets =========================================================== 2 | 3 | drug_targets <- fread("data/drug_targets.csv", 4 | stringsAsFactors = FALSE, 5 | data.table = FALSE) 6 | 7 | # Load results ================================================================ 8 | 9 | results <- data.frame(read_csv("data/mr_sbp_ad.csv")) 10 | results <- results[,c("leveli","method","nsnp","pval.mr","level" ,"or","uci","lci","methodtype")] 11 | 12 | # Remove results with no OR =================================================== 13 | 14 | results <- results[!is.na(results$or),] 15 | 16 | # Annotate gene and add drug info ============================================= 17 | 18 | results <- merge(results,drug_targets,by.x=c("leveli"),by.y=c("gene"),all.x = TRUE) 19 | results$drug <- ifelse(is.na(results$drug),results$leveli,results$drug) 20 | 21 | # Create OR labels ============================================================ 22 | 23 | results$orlab <- paste0("OR: ", 24 | ifelse(sprintf("%.2f",results$or)<0.0051, 25 | format(results$or,scientific = TRUE,digits=3), 26 | sprintf("%.2f",results$or)), 27 | " (95% CI: ", 28 | ifelse(sprintf("%.2f",results$lci)<0.0051, 29 | format(results$lci,scientific = TRUE,digits=3), 30 | sprintf("%.2f",results$lci)), 31 | " to ", 32 | ifelse(sprintf("%.2f",results$uci)<0.0051, 33 | format(results$uci,scientific = TRUE,digits=3), 34 | sprintf("%.2f",results$uci)), 35 | ")") 36 | 37 | results$orlab <- ifelse(results$pval.mr>=0.01 & results$pval.mr<=0.99, 38 | paste0(results$orlab,"; p = ", sprintf("%.2f",results$pval.mr),"; #SNPs = ",results$nsnp), 39 | results$orlab) 40 | 41 | results$orlab <- ifelse(results$pval.mr<0.01, 42 | paste0(results$orlab,"; p = ", sprintf("%.3f",results$pval.mr),"; #SNPs = ",results$nsnp), 43 | results$orlab) 44 | 45 | results$orlab <- ifelse(results$pval.mr<0.001, 46 | paste0(results$orlab,"; p < 0.001; #SNPs = ",results$nsnp), 47 | results$orlab) 48 | 49 | results$orlab <- ifelse(results$pval.mr>0.99, 50 | paste0(results$orlab,"; p > 0.99; #SNPs = ",results$nsnp), 51 | results$orlab) 52 | 53 | # Refine gene labels ========================================================== 54 | 55 | results$gene <- results$leveli 56 | results$gene <- ifelse(results$level=="Drug","All targets",results$gene) 57 | results$genelab <- ifelse(results$level %in% c("Overall","Combined"), 58 | paste0(results$orlab), 59 | paste0(results$gene,"; ",results$orlab)) 60 | results$genelab <- fct_rev(factor(results$genelab)) 61 | results$genelab <- factor(results$genelab,levels(results$genelab)[c(12:13,34:35,49:70,1:11,14:33,36:48,71:81)]) 62 | 63 | # Distinguish individual target results ======================================= 64 | 65 | results$alltargs <- ifelse(results$level=="Target","No","Yes") 66 | 67 | # Refine drug labels ========================================================== 68 | 69 | results$drug <- ifelse(results$level!="Target",results$leveli,results$drug) 70 | results$drug <- ifelse(results$drug=="Overall","Systolic blood pressure",results$drug) 71 | results$drug <- ifelse(results$drug=="Combined","Antihypertensive drugs",results$drug) 72 | results$drug <- fct_rev(factor(results$drug)) 73 | results$drug <- factor(results$drug,levels(results$drug)[c(3,10,14:11,9:4,2:1)]) 74 | 75 | # Plot target effects ========================================================= 76 | 77 | ggplot(results[results$methodtype=="main",], 78 | aes(x = genelab,y = or, col = alltargs)) + 79 | geom_point(aes(shape = alltargs)) + 80 | geom_linerange(aes(ymin = lci, ymax = uci)) + 81 | geom_hline(yintercept=1, linetype = 2) + 82 | scale_color_manual(values = c("#999999","black")) + 83 | scale_shape_manual(values=c(16,15))+ 84 | scale_x_discrete(name = "", position = "top") + 85 | scale_y_continuous(name = "OR and 95% CI for developing Alzheimer's disease for a 10mmHg\ndecrease in systolic blood pressure (presented on log scale)", 86 | trans = "log", breaks = c(1e-3,1,1e3)) + 87 | theme_minimal() + 88 | coord_flip() + 89 | facet_grid(drug~., scales = "free", space = "free", switch = "y") + 90 | theme(panel.grid.major.y = element_blank(), 91 | panel.grid.minor = element_blank(), 92 | axis.text=element_text(size=8), 93 | text=element_text(size=8), 94 | strip.text.y = element_text(size=8,hjust = 1, angle = 180), 95 | legend.position="none") 96 | 97 | ggsave("output/mr_sbp_ad_target.jpeg", height = 15, width = 13, unit = "cm", dpi = 600, scale = 1.75) 98 | 99 | # Plot drug class effects ========================================================= 100 | 101 | ggplot(results[results$methodtype=="main" & results$level!="Target",], 102 | aes(x = orlab,y = or, col = alltargs)) + 103 | geom_point(aes(shape = alltargs)) + 104 | geom_linerange(aes(ymin = lci, ymax = uci)) + 105 | geom_hline(yintercept=1, linetype = 2) + 106 | scale_color_manual(values = c("black")) + 107 | scale_x_discrete(name = "", position = "top") + 108 | scale_y_continuous(name = "OR and 95% CI for developing Alzheimer's disease for a 10mmHg\ndecrease in systolic blood pressure (presented on log scale)", 109 | trans = "log", breaks = c(0.1,1,10,100)) + 110 | theme_minimal() + 111 | coord_flip() + 112 | facet_grid(drug~., scales = "free", space = "free", switch = "y") + 113 | theme(panel.grid.major.y = element_blank(), 114 | panel.grid.minor = element_blank(), 115 | axis.text=element_text(size=8), 116 | text=element_text(size=8), 117 | strip.text.y = element_text(size=8,hjust = 1, angle = 180), 118 | legend.position="none") 119 | 120 | ggsave("output/mr_sbp_ad_class.jpeg", height = 7, width = 12, unit = "cm", dpi = 600, scale = 1.75) 121 | 122 | # Map main and sensitivity analyses to same label ============================= 123 | 124 | sensitivity <- results[results$level!="Target",] 125 | 126 | tmp <- sensitivity[,c("leveli","methodtype","orlab")] 127 | tmp <- spread(tmp, methodtype, orlab) 128 | tmp$sensitivity <- ifelse(is.na(tmp$sensitivity),"",tmp$sensitivity) 129 | sensitivity <- merge(sensitivity,tmp) 130 | 131 | # Refine drug labels in sensitivity dataset =================================== 132 | 133 | sensitivity$leveli <- ifelse(sensitivity$leveli=="Overall", 134 | "Systolic blood pressure", 135 | sensitivity$leveli) 136 | 137 | sensitivity$leveli <- ifelse(sensitivity$leveli=="Combined", 138 | "Antihypertensive drugs", 139 | sensitivity$leveli) 140 | 141 | sensitivity$druglab <- paste0(sensitivity$leveli," (# SNPs = ",sensitivity$nsnp, 142 | ")\n",sensitivity$main, 143 | "\n",sensitivity$sensitivity) 144 | 145 | sensitivity$druglab <- fct_rev(factor(sensitivity$druglab)) 146 | sensitivity$druglab <- factor(sensitivity$druglab,levels(sensitivity$druglab)[c(1:2,4:9,11:14,10,3)]) 147 | 148 | # Refine method label ========================================================= 149 | 150 | sensitivity$methodtype <- factor(sensitivity$methodtype) 151 | sensitivity$methodtype <- fct_rev(factor(sensitivity$methodtype)) 152 | 153 | # Plot sensitivity results ==================================================== 154 | 155 | ggplot(sensitivity[sensitivity$nsnp>=10,], aes(x = druglab,y = or,group = methodtype, shape = methodtype)) + 156 | geom_point(stat = "identity", position = position_dodge(width = 0.5)) + 157 | geom_linerange(aes(ymin = lci, ymax = uci), position = position_dodge(width = 0.5)) + 158 | geom_hline(yintercept=1, linetype = 2) + 159 | scale_shape_manual(name ="Method", 160 | breaks=c("main", "sensitivity"), 161 | labels=c("IVW", "MR-Egger"), 162 | values=c(17,15), 163 | guide = guide_legend(nrow = 1)) + 164 | scale_x_discrete(name = "") + 165 | scale_y_continuous(name = "OR and 95% CI for developing Alzheimer's disease for a 10mmHg\ndecrease in systolic blood pressure (presented on log scale)", 166 | trans = "log",breaks = c(0.1,1,10,100,1000)) + 167 | theme_minimal() + 168 | theme(panel.grid.major.y=element_blank(), 169 | panel.grid.minor = element_blank(), 170 | axis.text=element_text(size=8), 171 | text=element_text(size=8), 172 | strip.text.y = element_blank(), 173 | legend.position="bottom") + 174 | coord_flip() 175 | 176 | ggsave("output/mr_sbp_ad_egger.jpeg", height = 7, width = 12, unit = "cm", dpi = 600, scale = 1.75) 177 | --------------------------------------------------------------------------------