Skip to content

Commit 3bc7e51

Browse files
authored
Feature/vignettes and gwas upload (#20)
* Updating vignettes and removing api related Rd files * Updating vignettes * Removing unneccesary get trait param
1 parent 1e1ae2b commit 3bc7e51

41 files changed

Lines changed: 952 additions & 605 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.lintr

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
linters: linters_with_defaults(
2+
object_length_linter = object_length_linter(length = 50),
23
line_length_linter = line_length_linter(120),
34
return_linter = return_linter(return_style = "explicit"),
45
object_name_linter = NULL,

DESCRIPTION

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,13 @@ Imports:
1818
readr,
1919
tidyr
2020
Suggests:
21+
ggplot2,
22+
ggrepel,
2123
knitr,
24+
RColorBrewer,
25+
reshape2,
2226
rmarkdown,
27+
stringr,
2328
testthat (>= 3.0.0)
2429
Config/testthat/edition: 3
2530
VignetteBuilder: knitr

NAMESPACE

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,13 @@ export(genes)
88
export(get_all_gene_pleiotropies)
99
export(get_all_snp_pleiotropies)
1010
export(get_gwas)
11-
export(get_gwas_api)
1211
export(health_api)
1312
export(ld_matrix)
1413
export(ld_proxies)
1514
export(region)
1615
export(search_gpmap)
17-
export(select_api)
1816
export(trait)
1917
export(traits)
2018
export(upload_gwas)
2119
export(variant)
2220
export(variants)
23-
export(version_api)

R/api.r

Lines changed: 54 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ timeout_seconds <- 360
44
#' @description Select the API to use
55
#' @param api A character string specifying the API to use. Default is "production".
66
#' @return NULL
7-
#' @export
7+
#' @noRd
88
select_api <- function(api = "dev") {
99
if (api == "dev") {
1010
api_option <- options("gpmap_url" = "http://localhost:8000")
@@ -32,7 +32,7 @@ health_api <- function() {
3232
#' @title Get API Version
3333
#' @description Get the version of the API
3434
#' @return A list containing the version
35-
#' @export
35+
#' @noRd
3636
version_api <- function() {
3737
url <- paste0(getOption("gpmap_url"), "/v1/info/version")
3838
version <- httr::GET(url)
@@ -44,6 +44,7 @@ version_api <- function() {
4444
#' @title Search Options API
4545
#' @description Search options from the API
4646
#' @return A list containing the search options
47+
#' @noRd
4748
search_options_api <- function() {
4849
url <- paste0(getOption("gpmap_url"), "/v1/search/options")
4950
search_options <- httr::GET(url, httr::timeout(timeout_seconds))
@@ -57,6 +58,7 @@ search_options_api <- function() {
5758
#' @param query A character string specifying the query
5859
#' @param rsquared_threshold A numeric value specifying the rsquared threshold for the proxy variants
5960
#' @return A list containing the variants
61+
#' @noRd
6062
search_variants_api <- function(query, rsquared_threshold = 0.8) {
6163
url <- paste0(getOption("gpmap_url"), "/v1/search/variant/", query, "?rsquared_threshold=", rsquared_threshold)
6264
search_variants <- httr::GET(url, httr::timeout(timeout_seconds))
@@ -68,6 +70,7 @@ search_variants_api <- function(query, rsquared_threshold = 0.8) {
6870
#' @title Get All Traits API
6971
#' @description Get all traits from the API
7072
#' @return A list containing all traits
73+
#' @noRd
7174
traits_api <- function() {
7275
url <- paste0(getOption("gpmap_url"), "/v1/traits")
7376
traits <- httr::GET(url, httr::timeout(timeout_seconds))
@@ -83,6 +86,7 @@ traits_api <- function() {
8386
#' @param include_coloc_pairs A logical value specifying whether to include coloc pairs
8487
#' @param h4_threshold A numeric value specifying the h4 threshold for coloc pairs
8588
#' @return A list containing the traits
89+
#' @noRd
8690
specific_traits_api <- function(
8791
trait_ids,
8892
include_associations = FALSE,
@@ -106,6 +110,7 @@ specific_traits_api <- function(
106110
#' @param trait_id A character string specifying the trait ID
107111
#' @param include_associations A logical value specifying whether to include associations
108112
#' @return A list containing the trait
113+
#' @noRd
109114
trait_api <- function(trait_id, include_associations = FALSE) {
110115
url <- paste0(
111116
getOption("gpmap_url"),
@@ -118,6 +123,12 @@ trait_api <- function(trait_id, include_associations = FALSE) {
118123
return(trait)
119124
}
120125

126+
#' @title Get Trait Coloc Pairs API
127+
#' @description Get trait coloc pairs from the API
128+
#' @param trait_id A character string specifying the trait ID
129+
#' @param h4_threshold A numeric value specifying the h4 threshold for coloc pairs
130+
#' @return A list containing the trait coloc pairs
131+
#' @noRd
121132
trait_coloc_pairs_api <- function(trait_id, h4_threshold = 0.8) {
122133
url <- paste0(
123134
getOption("gpmap_url"),
@@ -135,6 +146,7 @@ trait_coloc_pairs_api <- function(trait_id, h4_threshold = 0.8) {
135146
#' @title Get Gene Information
136147
#' @description Get gene information from the API
137148
#' @return A list containing the genes
149+
#' @noRd
138150
genes_api <- function() {
139151
url <- paste0(getOption("gpmap_url"), "/v1/genes")
140152
genes <- httr::GET(url, httr::timeout(timeout_seconds))
@@ -151,6 +163,7 @@ genes_api <- function() {
151163
#' @param include_trans A logical value specifying whether to include trans genetic effects
152164
#' @param h4_threshold A numeric value specifying the h4 threshold for coloc pairs
153165
#' @return A list containing the genes
166+
#' @noRd
154167
specific_genes_api <- function(
155168
gene_ids,
156169
include_associations = FALSE,
@@ -180,6 +193,7 @@ specific_genes_api <- function(
180193
#' @param include_trans A logical value specifying whether to include trans genetic effects
181194
#' @param h4_threshold A numeric value specifying the h4 threshold for coloc pairs
182195
#' @return A list containing the gene information
196+
#' @noRd
183197
gene_api <- function(gene_id,
184198
include_associations = FALSE,
185199
include_coloc_pairs = FALSE,
@@ -207,6 +221,7 @@ gene_api <- function(gene_id,
207221
#' @param include_coloc_pairs A logical value specifying whether to include coloc pairs
208222
#' @param h4_threshold A numeric value specifying the h4 threshold for coloc pairs
209223
#' @return A list containing the region information
224+
#' @noRd
210225
region_api <- function(region_id, include_associations = FALSE, include_coloc_pairs = FALSE, h4_threshold = 0.8) {
211226
url <- paste0(
212227
getOption("gpmap_url"),
@@ -230,6 +245,7 @@ region_api <- function(region_id, include_associations = FALSE, include_coloc_pa
230245
#' @param include_coloc_pairs Logical. Whether to include coloc pairs for SNPs (only when expand=TRUE)
231246
#' @param h4_threshold Numeric. H4 threshold for coloc pairs, defaults to 0.8
232247
#' @return A list containing the variants
248+
#' @noRd
233249
variants_api <- function(variants, expand = FALSE, include_associations = FALSE, include_coloc_pairs = FALSE, h4_threshold = 0.8) {
234250
variants <- paste(variants, collapse = "&variants=")
235251
url <- paste0(getOption("gpmap_url"), "/v1/variants?variants=", variants)
@@ -245,11 +261,21 @@ variants_api <- function(variants, expand = FALSE, include_associations = FALSE,
245261
#' @param include_coloc_pairs Logical. Whether to include coloc pairs
246262
#' @param h4_threshold Numeric. H4 threshold for coloc pairs, defaults to 0.8
247263
#' @return A list containing the variants
264+
#' @noRd
248265
variants_grange_api <- function(chr, start, stop, include_associations = FALSE, include_coloc_pairs = FALSE, h4_threshold = 0.8) {
249266
url <- paste0(getOption("gpmap_url"), "/v1/variants?grange=", chr, ":", start, "-", stop)
250267
return(get_variants_with_options_api(url, expand = FALSE, include_associations, include_coloc_pairs, h4_threshold))
251268
}
252269

270+
#' @title Get Variants with Options API
271+
#' @description Get variants from the API with options
272+
#' @param url A character string specifying the URL
273+
#' @param expand A logical value specifying whether to expand the variants
274+
#' @param include_associations A logical value specifying whether to include associations
275+
#' @param include_coloc_pairs A logical value specifying whether to include coloc pairs
276+
#' @param h4_threshold A numeric value specifying the h4 threshold for coloc pairs
277+
#' @return A list containing the variants
278+
#' @noRd
253279
get_variants_with_options_api <- function(
254280
url,
255281
expand = FALSE,
@@ -275,6 +301,7 @@ get_variants_with_options_api <- function(
275301
#' @param include_coloc_pairs A logical value specifying whether to include coloc pairs
276302
#' @param h4_threshold A numeric value specifying the h4 threshold for coloc pairs
277303
#' @return A list containing the variant
304+
#' @noRd
278305
variant_api <- function(snp_id, include_coloc_pairs = FALSE, h4_threshold = 0.8) {
279306
url <- paste0(
280307
getOption("gpmap_url"),
@@ -293,6 +320,7 @@ variant_api <- function(snp_id, include_coloc_pairs = FALSE, h4_threshold = 0.8)
293320
#' @description Get variant summary statistics from the API
294321
#' @param snp_id A character string specifying the SNP ID
295322
#' @return A list containing dataframes from the TSV files
323+
#' @noRd
296324
variant_summary_stats_api <- function(snp_id) {
297325
temp_zip <- file.path(tempdir(), paste0("summary_stats_", snp_id, ".zip"))
298326

@@ -317,6 +345,7 @@ variant_summary_stats_api <- function(snp_id) {
317345
#' @description Get LD proxies from the API by Variant ID
318346
#' @param variants A character string specifying the Variant ID
319347
#' @return A list containing the LD proxies
348+
#' @noRd
320349
ld_proxies_by_variant_api <- function(variants) {
321350
variants <- paste(variants, collapse = "&variants=")
322351
url <- paste0(getOption("gpmap_url"), "/v1/ld/proxies?variants=", variants)
@@ -330,6 +359,7 @@ ld_proxies_by_variant_api <- function(variants) {
330359
#' @description Get LD proxies from the API by SNP ID
331360
#' @param snp_ids A character string specifying the SNP ID
332361
#' @return A list containing the LD proxies
362+
#' @noRd
333363
ld_proxies_by_snp_id_api <- function(snp_ids) {
334364
snp_ids <- paste(snp_ids, collapse = "&snp_ids=")
335365
url <- paste0(getOption("gpmap_url"), "/v1/ld/proxies?snp_ids=", snp_ids)
@@ -343,6 +373,7 @@ ld_proxies_by_snp_id_api <- function(snp_ids) {
343373
#' @description Get LD matrix from the API by Variant ID
344374
#' @param variants A character string specifying the Variant ID
345375
#' @return A list containing the LD matrix
376+
#' @noRd
346377
ld_matrix_by_variant_api <- function(variants) {
347378
variants <- paste(variants, collapse = "&variants=")
348379
url <- paste0(getOption("gpmap_url"), "/v1/ld/matrix?variants=", variants)
@@ -356,6 +387,7 @@ ld_matrix_by_variant_api <- function(variants) {
356387
#' @description Get LD matrix from the API by SNP ID
357388
#' @param snp_ids A character string specifying the SNP ID
358389
#' @return A list containing the LD matrix
390+
#' @noRd
359391
ld_matrix_by_snp_id_api <- function(snp_ids) {
360392
snp_ids <- paste(snp_ids, collapse = "&snp_ids=")
361393
url <- paste0(getOption("gpmap_url"), "/v1/ld/matrix?snp_ids=", snp_ids)
@@ -370,6 +402,7 @@ ld_matrix_by_snp_id_api <- function(snp_ids) {
370402
#' @param snp_ids A vector of numeric values specifying the SNP IDs
371403
#' @param study_ids A vector of numeric values specifying the Study IDs
372404
#' @return A list containing the associations
405+
#' @noRd
373406
associations_api <- function(snp_ids, study_ids) {
374407
snp_ids <- paste(snp_ids, collapse = "&snp_ids=")
375408
study_ids <- paste(study_ids, collapse = "&study_ids=")
@@ -384,6 +417,7 @@ associations_api <- function(snp_ids, study_ids) {
384417
#' @title Get All Gene Pleiotropies API
385418
#' @description Get all gene pleiotropies from the API
386419
#' @return A list containing the gene pleiotropies
420+
#' @noRd
387421
gene_pleiotropies_api <- function() {
388422
url <- paste0(getOption("gpmap_url"), "/v1/pleiotropy/genes")
389423
gene_pleiotropies <- httr::GET(url, httr::timeout(timeout_seconds))
@@ -395,6 +429,7 @@ gene_pleiotropies_api <- function() {
395429
#' @title Get All SNP Pleiotropies API
396430
#' @description Get all SNP pleiotropies from the API
397431
#' @return A list containing the SNP pleiotropies
432+
#' @noRd
398433
snp_pleiotropies_api <- function() {
399434
url <- paste0(getOption("gpmap_url"), "/v1/pleiotropy/snps")
400435
snp_pleiotropies <- httr::GET(url, httr::timeout(timeout_seconds))
@@ -407,10 +442,14 @@ snp_pleiotropies_api <- function() {
407442
#' @description Get a GWAS from the API
408443
#' @param gwas_id The ID of the GWAS
409444
#' @param include_summary_stats Whether to include summary statistics
445+
#' @param include_associations Whether to include associations
410446
#' @return A list containing the GWAS information
411-
#' @export
412-
get_gwas_api <- function(gwas_id, include_summary_stats = FALSE) {
447+
#' @noRd
448+
get_gwas_api <- function(gwas_id, include_summary_stats = FALSE, include_associations = FALSE) {
413449
url <- paste0(getOption("gpmap_url"), "/v1/gwas/", gwas_id)
450+
if (include_associations) {
451+
url <- paste0(url, "?include_associations=true")
452+
}
414453
gwas <- httr::GET(url, httr::timeout(timeout_seconds))
415454
gwas <- httr::content(gwas, "text", encoding = "UTF-8")
416455
gwas <- jsonlite::fromJSON(gwas)
@@ -421,6 +460,11 @@ get_gwas_api <- function(gwas_id, include_summary_stats = FALSE) {
421460
return(gwas)
422461
}
423462

463+
#' @title Get a GWAS Summary Stats API
464+
#' @description Get a GWAS summary stats from the API
465+
#' @param gwas_id The ID of the GWAS
466+
#' @return A list containing the GWAS summary stats
467+
#' @noRd
424468
get_gwas_summary_stats_api <- function(gwas_id) {
425469
url <- paste0(getOption("gpmap_url"), "/v1/gwas/", gwas_id, "/summary-stats")
426470
summary_stats <- httr::GET(url, httr::timeout(timeout_seconds))
@@ -451,7 +495,9 @@ get_gwas_summary_stats_api <- function(gwas_id) {
451495
#' @param ancestry The ancestry of the GWAS. Currently only "EUR" is accepted.
452496
#' @param sample_size The sample size of the GWAS
453497
#' @param reference_build The reference build of the GWAS. Only "GRCh37" and "GRCh38" are accepted.
498+
#' @param compare_with_upload_guids A vector of GUIDs of uploads to compare with
454499
#' @return A list containing the GWAS information
500+
#' @noRd
455501
upload_gwas_api <- function(file,
456502
name,
457503
p_value_threshold,
@@ -463,7 +509,8 @@ upload_gwas_api <- function(file,
463509
should_be_added = FALSE,
464510
ancestry = "EUR",
465511
sample_size,
466-
reference_build = "GRCh38") {
512+
reference_build = "GRCh38",
513+
compare_with_upload_guids = NA) {
467514
url <- paste0(getOption("gpmap_url"), "/v1/gwas")
468515

469516
gwas_request <- list(
@@ -477,7 +524,8 @@ upload_gwas_api <- function(file,
477524
ancestry = ancestry,
478525
sample_size = sample_size,
479526
p_value_threshold = p_value_threshold,
480-
column_names = column_names
527+
column_names = column_names,
528+
compare_with_upload_guids = compare_with_upload_guids
481529
)
482530
request_json <- jsonlite::toJSON(gwas_request, auto_unbox = TRUE)
483531

R/common.R

Lines changed: 59 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,23 +24,72 @@ is_guid <- function(id) {
2424
merge_associations <- function(coloc_groups, rare_results, associations) {
2525
if (is.null(associations)) return(coloc_groups = coloc_groups, rare_results = rare_results)
2626

27-
if (is.data.frame(coloc_groups) && nrow(coloc_groups) > 0) {
28-
coloc_groups <- dplyr::left_join(
29-
coloc_groups,
30-
associations,
31-
by = c("study_id", "snp_id")
32-
)
27+
join_keys <- c("study_id", "snp_id")
28+
if (!all(join_keys %in% colnames(associations))) {
29+
return(list(coloc_groups = coloc_groups, rare_results = rare_results))
3330
}
31+
associations <- dplyr::distinct(associations, dplyr::across(dplyr::all_of(join_keys)), .keep_all = TRUE)
3432

33+
if (is.data.frame(coloc_groups) && nrow(coloc_groups) > 0) {
34+
coloc_groups <- dplyr::left_join(coloc_groups, associations, by = join_keys)
35+
}
3536
if (is.data.frame(rare_results) && nrow(rare_results) > 0) {
36-
rare_results <- dplyr::left_join(
37-
rare_results,
37+
rare_results <- dplyr::left_join(rare_results, associations, by = join_keys)
38+
}
39+
40+
return(list(coloc_groups = coloc_groups, rare_results = rare_results))
41+
}
42+
43+
#' Merge associations into coloc info for GWAS upload results
44+
#'
45+
#' Joins associations using study_id when study_id is not NA, or existing_study_id
46+
#' when existing_study_id is not NA. GWAS uploads do not have rare results.
47+
#'
48+
#' @param coloc_groups A dataframe of coloc groups
49+
#' @param associations A dataframe of associations
50+
#' @return Coloc groups with associations merged in
51+
#' @keywords internal
52+
#' @noRd
53+
merge_gwas_upload_associations <- function(coloc_groups, associations) {
54+
if (is.null(associations)) return(coloc_groups)
55+
if (!is.data.frame(coloc_groups) || nrow(coloc_groups) == 0) return(coloc_groups)
56+
57+
study_rows <- coloc_groups[!is.na(coloc_groups[["study_id"]]), , drop = FALSE]
58+
existing_rows <- coloc_groups[
59+
is.na(coloc_groups[["study_id"]]) & !is.na(coloc_groups[["existing_study_id"]]),
60+
, drop = FALSE
61+
]
62+
other_rows <- coloc_groups[
63+
is.na(coloc_groups[["study_id"]]) & is.na(coloc_groups[["existing_study_id"]]),
64+
, drop = FALSE
65+
]
66+
parts <- list()
67+
68+
assoc_cols <- c("beta", "se", "p", "eaf", "imputed")
69+
assoc_cols <- intersect(assoc_cols, colnames(associations))
70+
71+
if (nrow(study_rows) > 0 && "study_id" %in% colnames(associations)) {
72+
assoc <- dplyr::distinct(associations, dplyr::across(dplyr::all_of(c("study_id", "snp_id"))), .keep_all = TRUE)
73+
assoc <- dplyr::select(assoc, dplyr::all_of(c("study_id", "snp_id", assoc_cols)))
74+
parts[[length(parts) + 1L]] <- dplyr::left_join(study_rows, assoc, by = c("study_id", "snp_id"))
75+
}
76+
if (nrow(existing_rows) > 0 && "existing_study_id" %in% colnames(associations)) {
77+
assoc <- dplyr::distinct(
3878
associations,
39-
by = c("study_id", "snp_id")
79+
dplyr::across(dplyr::all_of(c("existing_study_id", "snp_id"))),
80+
.keep_all = TRUE
4081
)
82+
assoc <- dplyr::select(assoc, dplyr::all_of(c("existing_study_id", "snp_id", assoc_cols)))
83+
parts[[length(parts) + 1L]] <- dplyr::left_join(existing_rows, assoc, by = c("existing_study_id", "snp_id"))
84+
}
85+
if (nrow(other_rows) > 0) {
86+
parts[[length(parts) + 1L]] <- other_rows
4187
}
4288

43-
return(list(coloc_groups = coloc_groups, rare_results = rare_results))
89+
if (length(parts) > 0) {
90+
return(dplyr::bind_rows(parts))
91+
}
92+
return(coloc_groups)
4493
}
4594

4695
#' Create a source url for a study

0 commit comments

Comments
 (0)