knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>"
)

1. Introduction

This vignette demonstrates how to analyse miRNA:Competing interactions via ceRNAnetsim package. The perturbations in the miRNA:target interactions are handled step by step in ceRNAnetsim. The package calculates and simulates regulation of miRNA:competing RNA interactions based on amounts of miRNA and the targets and interaction factors.

The ceRNAnetsim works by executing following steps:

The workflow of ceRNAnetsim are shown as following:

knitr::include_graphics("gifs/model_vignette.png")
library(ceRNAnetsim)

2. Installation

if (!requireNamespace("BiocManager", quietly = TRUE))
    install.packages("BiocManager")
BiocManager::install("ceRNAnetsim")

3. About the data

Below is the minimal data that can be used with ceRNAnetsim.

data("minsamp")
minsamp %>% 
  select(1:4)

The table is actually constructed by merging three different tables:

So, the basic_data table is constructed by merging following tables:

data("minsamp")
minsamp %>% 
  select(competing, Competing_expression) %>% 
  distinct() -> gene_expression
gene_expression
minsamp %>% 
  select(miRNA, miRNA_expression) %>% 
  distinct() -> mirna_expression
mirna_expression

Third table should contain miRNA:gene interactions per row. The ceRNAnetsim will assume first column contains competing RNA names and second column to be miRNA names. If the order is different the user should indicate column names accordingly.

minsamp %>% 
  select(competing, miRNA) -> interaction_simple
interaction_simple

The three tables can be joined in R (as shown below) or elsewhere to have interaction and expression data altogether in expected format.

interaction_simple %>%
  inner_join(gene_expression, by = "competing") %>%
  inner_join(mirna_expression, "miRNA") -> basic_data

basic_data

4. Simulation via expression values of miRNAs and genes in minsamp dataset

ceRNAnetsim processes your dataset as graph object and simulates competing behaviours of targets when steady-state is perturbed via expression level changes in one or more genes. Let's go over three steps:

4.1. Handle basic dataset

In first step, the expression and interaction table is converted into graph/network. tidygraph is used importing the data thus both node and edge data are accessible as tables if needed. priming_graph generates many columns in edge/node table which are mostly for internal use.

#Convertion of dataset to graph.

priming_graph(basic_data, competing_count = Competing_expression, miRNA_count =miRNA_expression)

4.2. Trigger a change

update_how function can be used to simulate a change in the network. (If multiple chnages are aimed to be used as trigger, update_variables() function should be used).

In the example below, expression level of "Gene2" is increased to two-fold.

priming_graph(basic_data, competing_count = Competing_expression, 
              miRNA_count =miRNA_expression) %>%
  update_how(node_name = "Gene2", how=2)

You can see the current count of Gene2 node is 20000 and its change is denoted as "Up" in changes_variable column in node table data.

4.3. Simulate the changes in graph

Finally, with the help of simulate function, the effect of expression change (i.e. the trigger) on overall network. The example code advances only for 5 cycles.

priming_graph(basic_data, competing_count = Competing_expression, 
              miRNA_count =miRNA_expression) %>%
  update_how(node_name = "Gene2", how=2) %>%
  simulate(cycle = 5)

count_current column indicate results after 5 cycle of calculations for each node. You can see the gene expression changes after this perturbation and simulation. This table can be obtained easily at following:

priming_graph(basic_data, competing_count = Competing_expression, 
              miRNA_count =miRNA_expression) %>%
  update_how(node_name = "Gene2", how=2) %>%
  simulate(cycle = 5)%>%
  as_tibble()%>%
  select(name, initial_count, count_current)

4.4. A special case: knockdown

ceRNAnetsim also provides the simulation of gene knockdown in the network. In normal conditions, when a gene is up or down regulated, it is considered that amounts of gene transcripts change depended on interactions. But, the transcripts of the gene are not observed in the system when it is knocked down. To achieve this case, you just need to define how argument to 0 (zero) in update_how function.

priming_graph(basic_data, competing_count = Competing_expression, 
              miRNA_count =miRNA_expression) %>%
  update_how(node_name = "Gene2", how=0) %>%
  simulate(cycle = 5)

So, if Gene2 is knocked down, there will be more miRNA (Mir1 to be exact) available for Gene1, Gene3 and Gene4, thus lowering their transcript levels. Since Gene4 is has lower expression level, we can observe minute changes in Gene5 and Gene6 levels due to more miRNA (Mir2) being available for them. These changes can be observed in current_count column.

Briefly, ceRNAnetsim utilizes the change(s) as trigger and calculates regulation of targets according to miRNA:target and target:total target ratios.

5. Simulation via interaction factors in addition to expression values of miRNAs and genes in minsamp dataset

Minimal sample minsamp is processed with priming_graph() function in first step. This provides conversion of dataset from data frame to graph object. This step comprises of:

minsamp
priming_graph(minsamp, 
              competing_count = Competing_expression, 
              miRNA_count = miRNA_expression,
              aff_factor = c(energy, seed_type), 
              deg_factor = region)

In the processed data, the values are carried as node variables and many more columns are initialized which are to be used in subsequent steps.

5.1. Change expression level of one or more nodes in the graph

In the steady-state, the miRNA degradation effect on gene expression is assumed to be stable (i.e. in equilibrium). But, if one or more nodes have altered expression level, the system tends to reach steady-state again.

The ceRNAnetsim package utilizes two methods to simulate change in expression level, update_how() and update_variables() functions provide unstable state from which calculations are triggered to reach steady-state.

If updating expression level of single node is desired then update_how() function should be used. In the example below, expression level of Gene4 is increased 2-fold.

minsamp %>%
   priming_graph(competing_count = Competing_expression, 
                 miRNA_count = miRNA_expression,
                 aff_factor = c(energy, seed_type), 
                 deg_factor = region) %>%
   update_how(node_name = "Gene4", how = 2) %>% 
   activate(edges)%>%
   # following line is just for focusing on necessary
   # columns to see the change in edge data
   select(3:4,comp_count_pre,comp_count_current)

The update_variables() function uses an external dataset which has number of rows equal to number of nodes in graph. The external dataset might include changed and unchanged expression values for each node.

Load the new_count dataset (provided with package sample data) in which expression level of Gene2 is increased 2 fold (from 10,000 to 20,000). Note that variables of the dataset included updated variables must be named as "Competing", "miRNA", "miRNA_count" and "Competing_count".

data(new_counts) 
new_counts

update_variables() function replaces the existing expression values with new values. The function checks for updates in all rows after importing expression values, thus it's possible to introduce multiple changes at once.

minsamp %>%
   priming_graph(competing_count = Competing_expression, 
                 miRNA_count = miRNA_expression,
                 aff_factor = c(energy, seed_type), 
                 deg_factor = region) %>%
   update_variables(current_counts = new_counts)

5.2. Update the node variables with edge variables.

The functions update_variables() and update_how() updates edge data. In these functions, update_nodes() function is applied in order to reflect changes in edge data over to node data. In other words, if there's a change in edge data, nodes can be updated accordingly with update_nodes() function.

minsamp %>%
  priming_graph(competing_count = Competing_expression, 
                miRNA_count = miRNA_expression,
                aff_factor = c(energy, seed_type), 
                deg_factor = region) %>%
  update_how("Gene4", how = 2) 

# OR
# minsamp %>%
#   priming_graph(competing_count = Competing_expression, 
#                 miRNA_count = miRNA_expression,
#                 aff_factor = c(energy, seed_type), 
#                 deg_factor = region) %>%
#   update_variables(current_counts = new_counts) 
knitr::include_graphics("gifs/small_sample_chunk10.png")

5.3. Simulate the model

Change in expression level of one or more nodes will trigger a perturbation in the system which will effect neighboring miRNA:target interactions. The effect will propagate and iterate over until it reaches steady-state.

With simulate() function the changes in the system, are calculated iteratively. For example, in the example below, simulation will proceed ten cycles only. In simulation of the regulation, the important argument is threshold which provides to specify absolute minimum amount of change required to be considered changed element as up or down.

minsamp %>%
  priming_graph(competing_count = Competing_expression, 
                miRNA_count = miRNA_expression,
                aff_factor = c(energy, seed_type), 
                deg_factor = region) %>%
  update_how("Gene4", how = 2) %>%
  simulate(cycle=10) #threshold with default 0.

simulate() saves the expression level of previous iterations in list columns in edge data. The changes in expression level throughout the simulate cycles are accessible with standard dplyr functions. For example:

minsamp %>%
   priming_graph(competing_count = Competing_expression, 
                 miRNA_count = miRNA_expression,
                 aff_factor = c(energy, seed_type), 
                 deg_factor = region) %>%
   update_how("Gene4", how = 2) %>%
   simulate(cycle=10) %>%
   activate(edges) %>%       #from tidygraph package 
   select(comp_count_list, mirna_count_list) %>%
   as_tibble()  

Here, comp_count_list and mirna_count_list are list-columns which track changes in both competing RNA and miRNA levels. In the sample above, "Gene4" has initial expression level of 10000 (after trigger, it's initial expression is 20000) and reached level of 19806 at 9th cycle (count_pre) and also stayed at 19806 in last cycle (count_current). The full history of expression level for Gene4 is as follows:

minsamp %>%
   priming_graph(competing_count = Competing_expression, 
                 miRNA_count = miRNA_expression,
                 aff_factor = c(energy, seed_type), 
                 deg_factor = region) %>%
   update_how("Gene4", how = 2) %>%
   simulate(cycle=10) %>%
   activate(edges) %>%       #from tidygraph package 
   select(comp_count_list, mirna_count_list) %>%
   as_tibble() %>% 
   filter(from==4, to==7) %>% 
   pull(comp_count_list) %>% 
   .[[1]] %>% 
   round()

Actually, Gene4 seems like reached steady-state in iteration 4. But, this approach is sensitive to even small decimal numbers. So, threshold argument could be used to ignore very small decimal numbers. With a threshold value the system can reach steady-state early, like following.

minsamp %>%
  priming_graph(competing_count = Competing_expression, 
                miRNA_count = miRNA_expression,
                aff_factor = c(energy, seed_type), 
                deg_factor = region) %>%
  update_how("Gene4", how = 2) %>%
  simulate(cycle=3, threshold = 1)

5.4. Visualisation of the graph

The vis_graph() function is used for visualization of the graph object. The initial graph object (steady-state) is visualized as following:

minsamp %>%
   priming_graph(competing_count = Competing_expression, 
                 miRNA_count = miRNA_expression,
                 aff_factor = c(energy, seed_type), 
                 deg_factor = region) %>%
   vis_graph(title = "Minsamp initial Graph")

Also, The graph can be visualized at any step of process, for example, after simulation of 3 cycles the graph will look like:

minsamp %>%
   priming_graph(competing_count = Competing_expression, 
                 miRNA_count = miRNA_expression,
                 aff_factor = c(energy, seed_type), 
                 deg_factor = region) %>%
   update_variables(current_counts = new_counts) %>%
   simulate(3) %>%
   vis_graph(title = "Minsamp Graph After 3 Iteration")

On the other hand, the network of each step can be plotted individually by using simulate_vis() function. simulate_vis() processes the given network just like simulate() function does while saving image of each step.

minsamp %>%
   priming_graph(competing_count = Competing_expression, 
                 miRNA_count = miRNA_expression,
                 aff_factor = c(energy, seed_type), 
                 deg_factor = region) %>%
   update_variables(current_counts = new_counts) %>%
   simulate_vis(3, title = "Minsamp Graph After Each Iteration")

Minsamp with 3 iteration

Note: Animated gif above was generated by online service. Actually, workflow gives the frames which include condition of each iteration. Note that you must use a terminal or online service, if you want to generate the animated gif.

6. Session Info

sessionInfo()

See the other vignettes for more information.



selcenari/ceRNAnetsim documentation built on Feb. 14, 2024, 4:20 a.m.