diff --git a/DESCRIPTION b/DESCRIPTION index e09a751..aa66ff6 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,5 +1,5 @@ Package: ariadne -Version: 0.2.6 +Version: 0.2.7 Authors@R: c(person(given = "Giulio", family = "Benedetti", role = c("aut", "cre"), email = "giulio.benedetti@utu.fi", @@ -37,7 +37,7 @@ Imports: ggplot2, ggraph, httr2, - igraph, + igraph (>= 2.3.0), KEGGREST, Matrix, methods, diff --git a/NEWS b/NEWS index 6521b3a..2b02246 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,6 @@ Changes in version 0.2.x * Made major changes to workflow -* Switched to S4 +* Switched back to S4 Changes in version 0.1.X * Switched to S7 diff --git a/R/data.R b/R/data.R index 881b3ac..aa5dcfa 100644 --- a/R/data.R +++ b/R/data.R @@ -26,3 +26,29 @@ #' @name butyrate #' @importFrom utils data NULL + + +#' Data frame for pathway from chebi to gmm +#' +#' \code{pathMeta} provides a minimal example of a data frame describing one +#' pathway in the ariadne graph from chebi to gmm. This kind of data frame is +#' typically the output of \code{\link{drawPath}} and works as input for +#' \code{\link{weavePath}} and \code{\link{weaveComplex}}. +#' +#' @returns +#' A pathway data frame with four rows (steps) and four columns (from, to, +#' source and version). +#' +#' @examples +#' # Import data frame for pathway from chebi to gmm +#' data("pathMeta", package = "ariadne") +#' +#' # Print pathway data frame +#' pathMeta +#' +#' # Recreate pathMeta using ariadne +#' # graph <- ariadne() +#' # pathMeta <- drawPath(graph, chebi ~ gmm, include = "rhea") +#' @name pathMeta +#' @importFrom utils data +NULL diff --git a/R/draw.R b/R/draw.R index 0744db2..9140f64 100644 --- a/R/draw.R +++ b/R/draw.R @@ -106,7 +106,7 @@ setMethod("drawPath", signature = c(graph = "igraph"), # Create path data.frame path_df <- data.frame( from = nodes[-length(nodes)], - to = nodes[-1], + to = nodes[-1L], source = edges ) return(path_df) diff --git a/R/plot.R b/R/plot.R index f5585d9..75ba4cb 100644 --- a/R/plot.R +++ b/R/plot.R @@ -57,10 +57,10 @@ setMethod("plotPath", signature = c(graph = "igraph"), function(graph, by = NULL, k = 1, include = NULL, exclude = NULL, res.name = NULL, prune = FALSE, focus = FALSE){ # Check args - if( !is.logical(prune) || length(prune) != 1L ){ + if( length(prune) != 1L || !is.logical(prune) || is.na(prune) ){ stop("'prune' must be TRUE or FALSE.", call. = FALSE) } - if( !is.logical(focus) || length(focus) != 1L ){ + if( length(focus) != 1L || !is.logical(focus) || is.na(focus) ){ stop("'focus' must be TRUE or FALSE.", call. = FALSE) } diff --git a/R/utils.R b/R/utils.R index 964cec0..95abe08 100644 --- a/R/utils.R +++ b/R/utils.R @@ -26,6 +26,9 @@ NULL #' @export #' @rdname listResourceVersions listResourceVersions <- function(default = FALSE){ + if( length(default) != 1L || !is.logical(default) || is.na(default) ){ + stop("'default' must be TRUE or FALSE.", call. = FALSE) + } # Retrieve metadata on resource versions meta <- versionMetadata # If default is turned on diff --git a/R/weave.R b/R/weave.R index 5c97ace..2c6e5bb 100644 --- a/R/weave.R +++ b/R/weave.R @@ -13,7 +13,8 @@ #' coverage threshold, which is useful for pathways or functional modules made #' of several indispensable components. #' -#' @param graph An igraph object. +#' @param graph An igraph or data.frame object, which can be obtained from +#' \code{\link{ariadne}} and \code{\link{drawPath}}, respectively. #' #' @param by A formula specifying the path to weave. #' @@ -65,15 +66,33 @@ #' column. #' #' @examples +#' # Load resource graph +#' graph <- ariadne() +#' +#' # Weave simple path from KEGG diseases to gut metabolic modules +#' dis2gmm <- weavePath(graph, kegg_disease ~ gmm) +#' +#' # Weave complex path from KEGG diseases to gut metabolic modules +#' dis2gmm <- weaveComplex(graph, kegg_disease ~ gmm) +#' +#' # Specify coverage threshold +#' dis2gmm <- weaveComplex(graph, kegg_disease ~ gmm, threshold = 0.8) +#' +#' +#' # Load example pathway dataframe +#' data("pathMeta", package = "ariadne") +#' +#' # Weave pathway from chebi to gmm with three initial chebi ids +#' chebi2gmm <- weavePath(pathMeta, init = c(15377, 30616, 4167)) +#' +#' +#' # Import mia package #' library(mia) #' #' # Import dataset #' data("Tengeler2020", package = "mia") #' tse <- Tengeler2020 #' -#' # Load resource graph -#' graph <- ariadne() -#' #' # Retrieve taxon names #' tax.labs <- getTaxonomyLabels(tse, make.unique = FALSE) #' tax.labs <- sub("^.+:", "", tax.labs) @@ -88,18 +107,59 @@ #' tax2bugsig <- weavePath( #' graph, taxname ~ bugsig, include = "taxid", init = tax.labs #' ) -#' -#' # Weave simple path from KEGG diseases to gut metabolic modules -#' dis2gmm <- weavePath(graph, kegg_disease ~ gmm) -#' -#' # Weave complex path from KEGG diseases to gut metabolic modules -#' dis2gmm <- weaveComplex(graph, kegg_disease ~ gmm) -#' -#' # Specify coverage threshold -#' dis2gmm <- weaveComplex(graph, kegg_disease ~ gmm, threshold = 0.8) NULL +#' @export +#' @rdname weavePath +#' @importFrom stats as.formula +setMethod("weavePath", signature = c(graph = "data.frame"), + function(graph, init = NULL, prune = TRUE, use.names = TRUE, verbose = TRUE, + timeout = 1e6, ...){ + # Derive formula from pathway dataframe + by <- c(graph$from[1L], graph$to[nrow(graph)]) |> + paste(collapse = "~") |> + as.formula() + # Retrieve minimal graph for the pathway + graph <- .graph_from_path_df(graph) + # Weave linkmap from minimal graph + linkmap <- weavePath( + graph, by, init = init, prune = prune, use.names = use.names, + verbose = verbose, timeout = timeout, ... + ) + return(linkmap) +}) + + +#' @importFrom igraph as_data_frame subgraph_from_edges +.graph_from_path_df <- function(path_df){ + # If versions are provided + if( "version" %in% names(path_df) ){ + # Derive versions from pathway dataframe + res_df <- unique(path_df[ , c("source", "version")]) + # Omit missing versions + res_df <- na.omit(res_df) + # Create versions list + versions <- as.list(res_df$version) + names(versions) <- res_df$source + }else{ + # Use empty versions + versions <- NULL + } + # Import ariadne graph + graph <- ariadne(versions = versions) + # Get keys of graph edges + E(graph)$name <- graph |> + as_data_frame(what = "edges") |> + .get_edge_keys() + # Get keys of pathway steps + keep <- .get_edge_keys(path_df) + # Subset graph based on pathway steps + graph <- subgraph_from_edges(graph, keep) + return(graph) +} + + #' @export #' @rdname weavePath #' @importFrom stats as.formula @@ -132,10 +192,10 @@ setMethod("weavePath", signature = c(graph = "igraph"), stop("'timeout' must be a positive number", call. = FALSE) } # Check shared logical args - if( !is.logical(prune) || length(prune) != 1L ){ + if( length(prune) != 1L || !is.logical(prune) || is.na(prune) ){ stop("'prune' must be TRUE or FALSE.", call. = FALSE) } - if( !is.logical(verbose) || length(verbose) != 1L ){ + if( length(verbose) != 1L || !is.logical(verbose) || is.na(verbose) ){ stop("'verbose' must be TRUE or FALSE.", call. = FALSE) } # Set timeout for downloads diff --git a/R/weave_complex.R b/R/weave_complex.R index d59c63c..63fab81 100644 --- a/R/weave_complex.R +++ b/R/weave_complex.R @@ -1,4 +1,25 @@ +#' @export +#' @rdname weavePath +#' @importFrom stats as.formula +setMethod("weaveComplex", signature = c(graph = "data.frame"), + function(graph, init = NULL, prune = TRUE, use.names = TRUE, + threshold = NULL, verbose = TRUE, timeout = 1e6, ...){ + + by <- c(graph$from[1L], graph$to[nrow(graph)]) |> + paste(collapse = "~") |> + as.formula() + + graph <- .graph_from_path_df(graph) + + linkmap <- weaveComplex( + graph, by, init = init, prune = prune, use.names = use.names, + threshold = threshold, verbose = verbose, timeout = timeout, ... + ) + return(linkmap) +}) + + #' @export #' @rdname weavePath #' @importFrom igraph as_data_frame @@ -36,7 +57,6 @@ setMethod("weaveComplex", signature = c(graph = "igraph"), }else{ inner_by <- by } - # Build MultiFactor from path linkmaps mf <- .build_path_mf( graph, inner_by, k, include, exclude, res.name, diff --git a/data/pathMeta.rda b/data/pathMeta.rda new file mode 100644 index 0000000..0d23789 Binary files /dev/null and b/data/pathMeta.rda differ diff --git a/man/pathMeta.Rd b/man/pathMeta.Rd new file mode 100644 index 0000000..538de16 --- /dev/null +++ b/man/pathMeta.Rd @@ -0,0 +1,26 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/data.R +\name{pathMeta} +\alias{pathMeta} +\title{Data frame for pathway from chebi to gmm} +\value{ +A pathway data frame with four rows (steps) and four columns (from, to, +source and version). +} +\description{ +\code{pathMeta} provides a minimal example of a data frame describing one +pathway in the ariadne graph from chebi to gmm. This kind of data frame is +typically the output of \code{\link{drawPath}} and works as input for +\code{\link{weavePath}} and \code{\link{weaveComplex}}. +} +\examples{ +# Import data frame for pathway from chebi to gmm +data("pathMeta", package = "ariadne") + +# Print pathway data frame +pathMeta + +# Recreate pathMeta using ariadne +# graph <- ariadne() +# pathMeta <- drawPath(graph, chebi ~ gmm, include = "rhea") +} diff --git a/man/weavePath.Rd b/man/weavePath.Rd index 48ff4fc..69e7eb5 100644 --- a/man/weavePath.Rd +++ b/man/weavePath.Rd @@ -3,7 +3,9 @@ \name{weavePath} \alias{weavePath} \alias{weaveComplex} +\alias{weavePath,data.frame-method} \alias{weavePath,igraph-method} +\alias{weaveComplex,data.frame-method} \alias{weaveComplex,igraph-method} \title{Weave paths between resources} \usage{ @@ -11,6 +13,16 @@ weavePath(graph, ...) weaveComplex(graph, ...) +\S4method{weavePath}{data.frame}( + graph, + init = NULL, + prune = TRUE, + use.names = TRUE, + verbose = TRUE, + timeout = 1e+06, + ... +) + \S4method{weavePath}{igraph}( graph, by, @@ -26,6 +38,17 @@ weaveComplex(graph, ...) ... ) +\S4method{weaveComplex}{data.frame}( + graph, + init = NULL, + prune = TRUE, + use.names = TRUE, + threshold = NULL, + verbose = TRUE, + timeout = 1e+06, + ... +) + \S4method{weaveComplex}{igraph}( graph, by, @@ -43,7 +66,8 @@ weaveComplex(graph, ...) ) } \arguments{ -\item{graph}{An igraph object.} +\item{graph}{An igraph or data.frame object, which can be obtained from +\code{\link{ariadne}} and \code{\link{drawPath}}, respectively.} \item{...}{Additional arguments. \itemize{ @@ -57,20 +81,6 @@ automatically detected when \code{NULL}. (Default: \code{NULL}) (Default: \code{3}) }} -\item{by}{A formula specifying the path to weave.} - -\item{k}{\code{Numeric scalar}. The kth shortest path to weave. -(Default: \code{1})} - -\item{include}{\code{Character vector}. Nodes to cross in the path. -(Default: \code{NULL})} - -\item{exclude}{\code{Character vector}. Nodes to avoid in the path. -(Default: \code{NULL})} - -\item{res.name}{\code{Character vector}. Names of resources to include in -the graph. (Default: \code{NULL})} - \item{init}{\code{Character vector}. Initial values to prune the first mapping step. (Default: \code{NULL})} @@ -86,6 +96,20 @@ console. (Default: \code{TRUE})} \item{timeout}{\code{Numeric scalar}. The timeout for downloading resources. (Default: \code{1e6})} +\item{by}{A formula specifying the path to weave.} + +\item{k}{\code{Numeric scalar}. The kth shortest path to weave. +(Default: \code{1})} + +\item{include}{\code{Character vector}. Nodes to cross in the path. +(Default: \code{NULL})} + +\item{exclude}{\code{Character vector}. Nodes to avoid in the path. +(Default: \code{NULL})} + +\item{res.name}{\code{Character vector}. Names of resources to include in +the graph. (Default: \code{NULL})} + \item{threshold}{\code{Numeric scalar}. Only for \code{weaveComplex}. The coverage threshold above which to include links, between 0 and 1. If \code{NULL}, all non-zero links are returned. (Default: \code{NULL})} @@ -105,15 +129,33 @@ coverage threshold, which is useful for pathways or functional modules made of several indispensable components. } \examples{ +# Load resource graph +graph <- ariadne() + +# Weave simple path from KEGG diseases to gut metabolic modules +dis2gmm <- weavePath(graph, kegg_disease ~ gmm) + +# Weave complex path from KEGG diseases to gut metabolic modules +dis2gmm <- weaveComplex(graph, kegg_disease ~ gmm) + +# Specify coverage threshold +dis2gmm <- weaveComplex(graph, kegg_disease ~ gmm, threshold = 0.8) + + +# Load example pathway dataframe +data("pathMeta", package = "ariadne") + +# Weave pathway from chebi to gmm with three initial chebi ids +chebi2gmm <- weavePath(pathMeta, init = c(15377, 30616, 4167)) + + +# Import mia package library(mia) # Import dataset data("Tengeler2020", package = "mia") tse <- Tengeler2020 -# Load resource graph -graph <- ariadne() - # Retrieve taxon names tax.labs <- getTaxonomyLabels(tse, make.unique = FALSE) tax.labs <- sub("^.+:", "", tax.labs) @@ -128,13 +170,4 @@ tax2bugsig <- weavePath(graph, taxname ~ bugsig, init = tax.labs, k = 3) tax2bugsig <- weavePath( graph, taxname ~ bugsig, include = "taxid", init = tax.labs ) - -# Weave simple path from KEGG diseases to gut metabolic modules -dis2gmm <- weavePath(graph, kegg_disease ~ gmm) - -# Weave complex path from KEGG diseases to gut metabolic modules -dis2gmm <- weaveComplex(graph, kegg_disease ~ gmm) - -# Specify coverage threshold -dis2gmm <- weaveComplex(graph, kegg_disease ~ gmm, threshold = 0.8) } diff --git a/pkgdown/_pkgdown.yml b/pkgdown/_pkgdown.yml index d35b560..ebd738e 100644 --- a/pkgdown/_pkgdown.yml +++ b/pkgdown/_pkgdown.yml @@ -21,3 +21,4 @@ reference: - title: Import package datasets - contents: - butyrate + - pathMeta diff --git a/tests/testthat/test-names.R b/tests/testthat/test-names.R index 90b6b4b..65a559b 100644 --- a/tests/testthat/test-names.R +++ b/tests/testthat/test-names.R @@ -1,29 +1,28 @@ test_that("names", { - - graph <- ariadne() - - expect_error( - linkNames(graph, "wrong"), "'x' must be in 'graph'.", fixed = TRUE - ) - - expect_error( - linkNames(graph, "ko", ids = "K0001", names = "alcohol dehydrogenase"), - "Either 'ids' or 'names' can be specified.", fixed = TRUE - ) - - x <- linkNames(graph, "gmm") - expect_named(x, c("gmm", "gmm.name")) - - name.vec <- c("alcohol dehydrogenase", "alditol oxidase") - x <- linkNames(graph, "ec", names = name.vec) - - expect_equal(x[[2L]], name.vec) - - expect_warning( - x <- linkNames(graph, "bugsig", ids = c("83/1/1", "wrong", "39/2/1")), - "names for 1 bugsig ids not found.", fixed = TRUE - ) - - expect_equal(is.na(x[[2L]]), c(FALSE, TRUE, FALSE)) - + + graph <- ariadne() + + expect_error( + linkNames(graph, "wrong"), "'x' must be in 'graph'.", fixed = TRUE + ) + + expect_error( + linkNames(graph, "ko", ids = "K0001", names = "alcohol dehydrogenase"), + "Either 'ids' or 'names' can be specified.", fixed = TRUE + ) + + x <- linkNames(graph, "gmm") + expect_named(x, c("gmm", "gmm.name")) + + name.vec <- c("alcohol dehydrogenase", "alditol oxidase") + x <- linkNames(graph, "ec", names = name.vec) + + expect_equal(x[[2L]], name.vec) + + expect_warning( + x <- linkNames(graph, "bugsig", ids = c("83/1/1", "wrong", "39/2/1")), + "names for 1 bugsig ids not found.", fixed = TRUE + ) + + expect_equal(is.na(x[[2L]]), c(FALSE, TRUE, FALSE)) }) \ No newline at end of file diff --git a/tests/testthat/test-plot.R b/tests/testthat/test-plot.R index 96f34a1..414547c 100644 --- a/tests/testthat/test-plot.R +++ b/tests/testthat/test-plot.R @@ -5,6 +5,16 @@ test_that("plot", { expect_error(plotPath(ec ~ ko)) + expect_error( + plotPath(graph, ec ~ ko, focus = "wrong"), + "'focus' must be TRUE or FALSE." + ) + + expect_error( + plotPath(graph, prune = TRUE), + "'prune' must be FALSE when 'by' is not defined." + ) + p <- plotPath(graph) pdata <- ggplot2::ggplot_build(p)$data @@ -15,14 +25,23 @@ test_that("plot", { p <- plotPath(graph, ec ~ ko, prune = TRUE) pdata <- ggplot2::ggplot_build(p)$data - expect_in(pdata[[1]]$edge_colour, c("grey80", "red")) - expect_in(pdata[[1]]$edge_alpha, c(FALSE, TRUE)) + expect_contains(pdata[[1]]$edge_colour, c("grey80", "red")) + expect_contains(pdata[[1]]$edge_alpha, c(FALSE, TRUE)) expect_identical(nrow(pdata[[2]]), 2L) - expect_error(plotPath(graph, ec ~ ko, focus = "wrong")) + nodes <- sum(!is.na(igraph::V(graph)$KEGG) | !is.na(igraph::V(graph)$Rhea)) - expect_error( - plotPath(graph, prune = TRUE), - "'prune' must be FALSE when 'by' is not defined." - ) + p <- plotPath(graph, res.name = c("KEGG", "Rhea")) + pdata <- ggplot2::ggplot_build(p)$data + + expect_in(pdata[[1]]$edge_colour, "grey80") + expect_contains(pdata[[1]]$edge_alpha, c(FALSE, TRUE)) + expect_identical(nrow(pdata[[2]]), nodes) + + p <- plotPath(graph, res.name = c("KEGG", "Rhea"), focus = TRUE) + pdata <- ggplot2::ggplot_build(p)$data + + expect_in(pdata[[1]]$edge_colour, "grey80") + expect_in(pdata[[1]]$edge_alpha, TRUE) + expect_identical(nrow(pdata[[2]]), nodes) }) diff --git a/tests/testthat/test-search.R b/tests/testthat/test-search.R index b4408ae..2c20664 100644 --- a/tests/testthat/test-search.R +++ b/tests/testthat/test-search.R @@ -1,4 +1,3 @@ - test_that("search", { graph <- ariadne() diff --git a/tests/testthat/test-utils.R b/tests/testthat/test-utils.R index 5a13f15..ab68095 100644 --- a/tests/testthat/test-utils.R +++ b/tests/testthat/test-utils.R @@ -1,6 +1,47 @@ - test_that("utils", { - expect_no_error(1 + 1) + expect_error( + listResourceVersions(default = c(NA, NA)), + "'default' must be TRUE or FALSE." + ) + meta <- listResourceVersions() + default <- listResourceVersions(default = TRUE) + + expect_gt(anyDuplicated(meta$resource), 0L) + expect_equal(anyDuplicated(default$resource), 0L) + + + set.seed(123) + + gene_ids <- c( + "Unbinned", + "uniref90|Bacteroides.thetaiotaomicron", + "uniref90|Escherichia.coli", + "uniref90|Faecalibacterium.prausnitzii", + "uniref90|unclassified", + "uniref90|Bifidobacterium.adolescentis", + "uniref90|Lactobacillus.rhamnosus" + ) + + # Create a matrix of random counts (e.g., 6 genes x 10 samples) + count_matrix <- matrix( + data = sample(10:1000, size = 10 * length(gene_ids), replace = TRUE), + nrow = length(gene_ids) + ) + + rownames(count_matrix) <- gene_ids + + # Create the SummarizedExperiment object + se <- SummarizedExperiment::SummarizedExperiment( + assays = list(counts = count_matrix) + ) + + se <- processGeneFamilies(se) + + expect_s4_class(se, "SummarizedExperiment") + expect_contains( + names(SummarizedExperiment::rowData(se)), + c("uniref90", "taxname", "genus", "species") + ) }) \ No newline at end of file diff --git a/tests/testthat/test-weave.R b/tests/testthat/test-weave.R index c37f233..cbd6556 100644 --- a/tests/testthat/test-weave.R +++ b/tests/testthat/test-weave.R @@ -1,15 +1,14 @@ - test_that("weave", { graph <- ariadne() - path_df <- .draw_path(graph, bugsig ~ ko, 1, "uniref90", "taxid", NULL) + path_df <- drawPath(graph, bugsig ~ ko, 1, "uniref90", "taxid") expect_false("taxid" %in% path_df$from || "taxid" %in% path_df$to) expect_true("uniref90" %in% path_df$from || "taxid" %in% path_df$to) expect_error( - .draw_path(graph, bugsig ~ ko, 1, "uniref90", "uniref90"), + drawPath(graph, bugsig ~ ko, 1, "uniref90", "uniref90"), "'include' and 'exclude' cannot overlap." ) @@ -26,4 +25,13 @@ test_that("weave", { ec2gmm <- weaveComplex(graph, ec ~ gmm) expect_identical(colnames(ec2gmm), c("ec", "gmm", "cov", "gmm.name")) + + data("pathMeta", package = "ariadne") + chebi_ids <- c(15377, 30616, 4167) + + chebi2gmm <- weavePath(pathMeta, init = chebi_ids) + + expect_s3_class(chebi2gmm, "data.frame") + expect_s3_class(chebi2gmm$gmm, "factor") + expect_contains(levels(chebi2gmm$chebi), chebi_ids) }) \ No newline at end of file diff --git a/vignettes/gsea.Rmd b/vignettes/gsea.Rmd index 4420be3..dacb4cd 100644 --- a/vignettes/gsea.Rmd +++ b/vignettes/gsea.Rmd @@ -22,52 +22,54 @@ vignette: > %\VignetteEncoding{UTF-8} --- +Should use SE transcriptomics dataset instead? + ```{r, include=FALSE} -knitr::opts_chunk$set( - collapse = TRUE, - comment = "#>" -) +#knitr::opts_chunk$set( +# collapse = TRUE, +# comment = "#>" +#) ``` ## Gene Expression Omnibus ```{r} -library(ariadne) -library(GEOquery) +#library(ariadne) +#library(GEOquery) ``` ```{r} -eList <- getGEO("GSE11675") +#eList <- getGEO("GSE11675") -eData <- eList[[1]] +#eData <- eList[[1]] -eData +#eData ``` ```{r} -head(exprs(eData)) +#head(exprs(eData)) ``` ```{r} -genes <- featureData(eData)@data$ENTREZ_GENE_ID +#genes <- featureData(eData)@data$ENTREZ_GENE_ID -head(genes) +#head(genes) ``` ```{r} -graph <- ariadne() +#graph <- ariadne() ``` ```{r} -plotPath(graph, geneid ~ msig, prune = TRUE, focus = TRUE) +#plotPath(graph, geneid ~ msig, prune = TRUE, focus = TRUE) ``` ```{r} -gene2msig <- weavePath(graph, geneid ~ msig, init = genes) +#gene2msig <- weavePath(graph, geneid ~ msig, init = genes) -head(gene2msig) +#head(gene2msig) ``` # Reproducibility