Commit 746ca8cf authored by Leon-Charles Tranchevent's avatar Leon-Charles Tranchevent
Browse files

New integration strategy using a confidence score.

parent 2e2c6df9
......@@ -29,17 +29,17 @@ rm(output_data_dir)
# Load the prepared SCAN log file with the number of iterations and proportion of background
# probes per sample for each dataset.
SCAN_log <- read_delim(input_data_file, "\t", escape_double = FALSE, trim_ws = TRUE)
scan_log <- read_delim(input_data_file, "\t", escape_double = FALSE, trim_ws = TRUE)
message(paste0("[", Sys.time(), "] Data read."))
# We prepare the data for ggplot by adding extra columns to define classes.
D <- SCAN_log %>%
d <- scan_log %>%
dplyr::mutate(class_tag = ifelse(convergence < 1,
ifelse(prop_back < 0.85,
"Normal",
"High background (>85% probes)")
, "No convergence"))
rm(SCAN_log)
rm(scan_log)
message(paste0("[", Sys.time(), "] Data filtered."))
# Scatter plot of the number of iterations vs the proportion of background probes per dataset.
......@@ -47,7 +47,7 @@ message(paste0("[", Sys.time(), "] Data filtered."))
# Another distinction is made for points with a convergence higher than 1.0 (i.e., considered
# as no convergence).
png(output_figure_file, width = 1600, height = 1600, units = "px", res = 300)
myplot <- ggplot(D, aes(x = nb_iterations, y = prop_back, colour = class_tag)) +
myplot <- ggplot(d, aes(x = nb_iterations, y = prop_back, colour = class_tag)) +
geom_jitter(size = 3, alpha = 0.66) +
facet_wrap(dataset ~ .) +
theme(legend.position = "bottom", legend.title = element_blank(),
......@@ -63,8 +63,8 @@ rm(output_figure_file, myplot)
message(paste0("[", Sys.time(), "] Plot created."))
# We save the file for later use (just in case)
write_csv(D, path = input_data_file)
rm(D, input_data_file)
write_csv(d, path = input_data_file)
rm(d, input_data_file)
message(paste0("[", Sys.time(), "] Data saved."))
# We log the session details for reproducibility.
......
......@@ -34,15 +34,15 @@ message(paste0("[", Sys.time(), "] Configuration done."))
# ================================================================================================
#' @title Run the VSN method for a given configuration.
#'
#' @description This methods takes a given configuration and run VSN on it to try to stablize the
#'
#' @description This methods takes a given configuration and run VSN on it to try to stablize the
#' variance. It creates several plots before and after VSN is applied and also save the entire
#' expression matrix after the correction.
#'
#'
#' @param output_data_subdir The folder in chich the expression data is stored. It will also be
#' used to store the figures and the corrected data.
#' @param dataset_name The name of the dataset to consider.
#' @param normalization_name The name of the normalization with which the dataset was
#' @param normalization_name The name of the normalization with which the dataset was
#' pre-processed.
#' @param batchcorrectin_tag The batch correction tag used to the name the files.
run_vsn <- function(output_data_subdir, dataset_name, normalization_name, batchcorrection_tag) {
......
......@@ -32,14 +32,14 @@ message(paste0("[", Sys.time(), "] Configuration done."))
# Functions
# ================================================================================================
#' @title Function that estimate the importance of a feature.
#'
#'
#' @description This function computes two correlations (Pearson and Spearman) between a feature
#' vector and a response vector. It then return the maximum absolute value among the two
#' vector and a response vector. It then return the maximum absolute value among the two
#' (as to take into account both correlation and anti-correlation).
#'
#'
#' @param x The feature vector.
#' @param resp The response vector.
#' @return The maximum absolute correlation bewteen x and resp.
#' @return The maximum absolute correlation bewteen x and resp.
estimate_importance <- function(x, resp) {
pcor <- cor(x, resp, method = "pearson")
scor <- cor(x, resp, method = "spearman")
......@@ -66,8 +66,9 @@ for (i in seq_len(length(config$datasets))) {
# We load the data (clinical).
pheno_data <- Biobase::pData(ArrayUtils::load_clinical_data(raw_data_subdir))
pheno_data <- pheno_data %>% dplyr::mutate(cel_name = row.names(pheno_data)) %>%
dplyr::mutate(Age = as.numeric(as.character(Age)))
pheno_data <- pheno_data %>%
dplyr::mutate(cel_name = row.names(pheno_data)) %>%
dplyr::mutate(Age = as.numeric(as.character(Age)))
age_sd <- round(sd(pheno_data$Age, na.rm = TRUE), 1)
# If there is no patient age at all, we skip the dataset since we can not make predictions.
......@@ -113,7 +114,8 @@ for (i in seq_len(length(config$datasets))) {
# (A) We keep only the full profiles (no real NA).
message(paste0("[", Sys.time(), "] [", dataset_name, "][", normalization_name,
"] [", bc_tag, "] Starting cross-validation."))
nomissing_samples <- pheno_data %>% dplyr::filter(!is.na(Age)) %>%
nomissing_samples <- pheno_data %>%
dplyr::filter(!is.na(Age)) %>%
dplyr::select(cel_name, Age, Gender, Disease.status)
nomissing_samples$cel_name <- gsub(".txt", "", nomissing_samples$cel_name)
nomissing_ages <- nomissing_samples$Age
......@@ -281,7 +283,7 @@ local_max <- max(loocv_all$Age, loocv_all$Pred) * 1.05
png(plot_name)
p <- ggplot(loocv_all, aes(x = Age, y = Pred, color = abs(Age - Pred))) +
theme(legend.position = "None") +
facet_wrap( ~ dataset) +
facet_wrap(~ dataset) +
coord_cartesian(xlim = c(local_min, local_max), ylim = c(local_min, local_max)) +
geom_abline(intercept = 0, slope = 1, colour = "darkgrey") +
geom_abline(intercept = -5, slope = 1, colour = "darkgrey", linetype = 2) +
......
......@@ -6,6 +6,7 @@
library("yaml")
library("ArrayUtils")
library("tidyverse")
library("dendextend")
source("../libs/conf/confR.R")
message(paste0("[", Sys.time(), "] Libraries loaded."))
......@@ -32,7 +33,7 @@ message(paste0("[", Sys.time(), "] Configuration done."))
# ================================================================================================
#' @title Heatmap of an expression dataset.
#'
#'
#' @description This function plots the expression signal on a heatmap. The objective is to
#' provide a subset of the full expression dataset (e.g., only the Y-chromosome probes) and
#' see if the clustering (on top of the heatmap) correlates with the provided phenotypic
......@@ -53,7 +54,8 @@ plot_heatmap_expr_signal <- function(mat, pheno_data, plot_filename, verbose = T
# Plot the heatmap.
png(plot_filename)
heatmap(mat, ColSideColors = sample_cols)
dendo <- dendextend::set(as.dendrogram(hclust(dist(t(mat)))), "branches_lwd", 3)
heatmap(mat, ColSideColors = sample_cols, Colv = dendo)
dev.off()
# We clean up and log information.
......@@ -64,7 +66,7 @@ plot_heatmap_expr_signal <- function(mat, pheno_data, plot_filename, verbose = T
}
#' @title Regular plot of a ratio signal for a list of samples.
#'
#'
#' @description This function plots X versus Y expression signal. First, the X- and
#' Y-signals are derived by taking the mean signal over X- and Y- probes. Then the
#' ratio is plotted for all samples and samples are coloured according to the known
......@@ -91,8 +93,22 @@ plot_expr_ratios <- function(mat_x, mat_y, pheno_data, plot_filename, verbose =
# Simple plot (accross samples) to see if that signal can discriminate females and males.
png(plot_filename)
plot(y_vs_x_ratios, col = sample_cols, pch = 21, bg = sample_cols)
dev.off()
plot(y_vs_x_ratios, col = sample_cols, pch = 21, bg = sample_cols,
font = 2, cex.axis = 1.5, cex.main = 1.5, xaxt = "n",
main = dataset$dataset_name,
xlab = "",
ylab = "",
cex = 1.5,
lwd = 2)
mtext("Y- vs X-chrom avg expr", side = 2, line = 3, cex = 1.5, font = 2)
legend(x = "left",
legend = c("Females", "Males"),
col = c("blue", "green"),
pch = 19,
cex = 1.5,
lwd = 2,
text.font = 2)
dev.off()
# We clean up and log information.
rm(xsignal_means, ysignal_means, y_vs_x_ratios, sample_gender, sample_cols)
......
#!/usr/bin/env Rscript
# ================================================================================================
# Libraries
# ================================================================================================
library("yaml")
library("ArrayUtils")
library("tidyverse")
library("dendextend")
source("../libs/conf/confR.R")
message(paste0("[", Sys.time(), "] Libraries loaded."))
# ================================================================================================
# Configuration
# ================================================================================================
options(bitmapType = "cairo")
config <- read_config(config_dirs = c("../Confs/", "./"))
raw_data_dir <- config$global_raw_data_dir
output_data_dir <- paste0(config$global_data_dir, config$local_data_dir)
input_data_dir <- paste0(config$global_data_dir, config$local_input_data_dir)
# Optional command line parameter to process only one dataset.
args <- commandArgs(trailingOnly = TRUE)
selected_dataset_name <- ""
if (length(args) > 0) {
selected_dataset_name <- args[1]
}
rm(args)
message(paste0("[", Sys.time(), "] Configuration done."))
# ================================================================================================
# Functions
# ================================================================================================
#' @title Heatmap of an expression dataset.
#'
#' @description This function plots the expression signal on a heatmap. The objective is to
#' provide a subset of the full expression dataset (e.g., only the Y-chromosome probes) and
#' see if the clustering (on top of the heatmap) correlates with the provided phenotypic
#' descriptor (e.g., gender).
#'
#' @param mat The matrix containing the expression data to analyze.
#' @param pheno_data The clinical data of the dataset (if known), used to enrich the plot.
#' @param plot_filename The full path to the file where the heatmap should be saved.
#' @param verbose A boolean representing whether the function should display log information. This
#' is TRUE by default.
plot_heatmap_expr_signal <- function(mat, pheno_data, plot_filename, verbose = TRUE) {
# Prepare colours for the heatmap.
sample_gender <- Biobase::pData(pheno_data)$Gender
sample_cols <- rep("grey", length(sample_gender))
sample_cols[sample_gender == "M"] <- "green"
sample_cols[sample_gender == "F"] <- "blue"
# Plot the heatmap.
png(plot_filename)
dendo <- set(as.dendrogram(hclust(dist(t(mat)))), "branches_lwd", 3)
heatmap(mat, ColSideColors = sample_cols, Colv = dendo)
dev.off()
# We clean up and log information.
rm(sample_gender, sample_cols)
if (verbose == TRUE) {
message(paste0("[", Sys.time(), "] Heatmap created."))
}
}
#' @title Regular plot of a ratio signal for a list of samples.
#'
#' @description This function plots X versus Y expression signal. First, the X- and
#' Y-signals are derived by taking the mean signal over X- and Y- probes. Then the
#' ratio is plotted for all samples and samples are coloured according to the known
#' phenotypic descriptor (e.g., gender).
#'
#' @param mat_x The matrix containing the expression data for the X-chromosome probes.
#' @param mat_y The matrix containing the expression data for the Y-chromosome probes.
#' @param pheno_data The clinical data of the dataset (if known), used to enrich the plot.
#' @param plot_filename The full path to the file where the simple plot should be saved.
#' @param verbose A boolean representing whether the function should display log information. This
#' is TRUE by default.
plot_expr_ratios <- function(mat_x, mat_y, pheno_data, plot_filename, verbose = TRUE) {
# Prepare colours for the plot.
sample_gender <- Biobase::pData(pheno_data)$Gender
sample_cols <- rep("grey", length(sample_gender))
sample_cols[sample_gender == "M"] <- "green"
sample_cols[sample_gender == "F"] <- "blue"
# We prepare the data (X vs Y signal).
xsignal_means <- apply(mat_x, 2, mean)
ysignal_means <- apply(mat_y, 2, mean)
y_vs_x_ratios <- ysignal_means / xsignal_means
# Simple plot (accross samples) to see if that signal can discriminate females and males.
png(plot_filename)
plot(y_vs_x_ratios, col = sample_cols, pch = 21, bg = sample_cols,
font = 2, cex.axis = 1.5, cex.main = 1.5, xaxt = "n",
main = dataset$dataset_name,
xlab = "",
ylab = "",
cex = 1.5,
lwd = 2)
mtext("Y- vs X-chrom avg expr", side=2, line=3, cex=1.5, font = 2)
legend(x = "left",
legend = c("Females", "Males"),
col = c("blue", "green"),
pch = 19,
cex = 1.5,
lwd = 2,
text.font = 2)
dev.off()
# We clean up and log information.
rm(xsignal_means, ysignal_means, y_vs_x_ratios, sample_gender, sample_cols)
if (verbose == TRUE) {
message(paste0("[", Sys.time(), "] Simple plot created."))
}
}
# ================================================================================================
# Main
# ================================================================================================
# We do all datasets one by one.
for (i in seq_len(length(config$datasets))) {
# We get the dataset details.
dataset <- config$datasets[[i]]
dataset_name <- dataset$dataset_name
# We predict the gender on the current dataset (if necessary).
if (selected_dataset_name == "" || selected_dataset_name == dataset_name) {
# We define the I/Os.
raw_data_subdir <- paste0(raw_data_dir, dataset_name, "/")
output_data_subdir <- paste0(output_data_dir, dataset_name, "/")
# We load the data (clinical, X- and Y-chromosome probes).
pheno_data <- ArrayUtils::load_clinical_data(raw_data_subdir)
probe_list_names <- paste0(dataset$array_type, c("_chromX", "_chromY"))
array_probes <- read_probe_lists(probe_list_names,
output_data_dir,
filename_prefix = "",
filename_suffix = ".tsv")
# We then repeat the analysis for all normalization configurations.
for (j in seq_len(length(config$normalizations))) {
# We get the normalization details.
normalization <- config$normalizations[[j]]
normalization_name <- normalization$name
# We also repeat the analysis for batch corrected / uncorrected data.
for (bc_tag in c("batchcorrection", "nobatchcorrection")) {
# We define the expression data file name.
exp_data_fn <- paste0(input_data_dir, dataset_name, "/", normalization_name,
"/", dataset_name, "_normalized_", normalization_name,
"_", bc_tag, ".tsv")
# We check if the file exists (because some datasets have no documented batch).
if (file.exists(exp_data_fn)) {
# We load the corresponding expression data matrix.
message(paste0("[", Sys.time(), "] [", dataset_name, "][", normalization_name,
"] [", bc_tag, "] Starting gender prediction."))
exp_data <- ArrayUtils::read_eset(exp_data_fn, as_eset = FALSE)
# We remove the probes that target both X and Y regions since they will likely
# contaminate our analysis.
array_xprobes <- setdiff(rownames(array_probes[[1]]), rownames(array_probes[[2]]))
array_yprobes <- setdiff(rownames(array_probes[[2]]), rownames(array_probes[[1]]))
# Subset the expression matrices with the X- and Y-chromosome probes.
array_xprobes <- intersect(array_xprobes, rownames(exp_data))
array_yprobes <- intersect(array_yprobes, rownames(exp_data))
exp_data_xonly <- exp_data[array_xprobes, ]
exp_data_yonly <- exp_data[array_yprobes, ]
rm(exp_data, array_xprobes, array_yprobes)
# Heatmaps to check if clustering/discrimination is working.
plot_filename <- paste0(output_data_subdir, dataset_name, "_", normalization_name,
"_", bc_tag, "_heatmap_yprobes.png")
plot_heatmap_expr_signal(exp_data_yonly, pheno_data, plot_filename)
# Plot of the Y vs X signal.
plot_filename <- paste0(output_data_subdir, dataset_name, "_", normalization_name,
"_", bc_tag, "_plot_YvsX.png")
plot_expr_ratios(exp_data_xonly, exp_data_yonly, pheno_data, plot_filename)
rm(exp_data_xonly, exp_data_yonly)
message(paste0("[", Sys.time(), "] [", dataset_name, "][", normalization_name,
"] [", bc_tag, "] Ending gender prediction."))
} # End if file exists.
rm(exp_data_fn)
} # End for each batch correction case.
rm(normalization, normalization_name, bc_tag)
} # End for each normalization.
rm(j, raw_data_subdir, output_data_subdir, pheno_data, probe_list_names, array_probes)
} # End if dataset should be analysed.
rm(dataset, dataset_name)
} # End for each dataset.
# We log the session details for reproducibility.
rm(i, selected_dataset_name, output_data_dir, input_data_dir, raw_data_dir, config)
sessionInfo()
......@@ -72,17 +72,17 @@ for (i in seq_len(length(config$datasets))) {
# First version, one colour per category.
# We prepare the subplots one by one.
p12 <- ggplot(pca_coords, aes(x = PC1, y = PC2, color = group )) +
p12 <- ggplot(pca_coords, aes(x = PC1, y = PC2, color = group)) +
geom_point(size = 5) +
theme(legend.position = "None") +
xlab(percentage[1]) +
ylab(percentage[2])
p13 <- ggplot(pca_coords, aes(x = PC1, y = PC3, color = group )) +
p13 <- ggplot(pca_coords, aes(x = PC1, y = PC3, color = group)) +
geom_point(size = 5) +
theme(legend.position = "bottom") +
xlab(percentage[1]) +
ylab(percentage[3])
p23 <- ggplot(pca_coords, aes(x = PC2, y = PC3, color = group )) +
p23 <- ggplot(pca_coords, aes(x = PC2, y = PC3, color = group)) +
geom_point(size = 5) +
theme(legend.position = "None") +
xlab(percentage[2]) +
......@@ -110,17 +110,17 @@ for (i in seq_len(length(config$datasets))) {
pca_coords$binary_groups <- binary_groups
# We prepare the subplots one by one.
p12 <- ggplot(pca_coords, aes(x = PC1, y = PC2, color = binary_groups )) +
p12 <- ggplot(pca_coords, aes(x = PC1, y = PC2, color = binary_groups)) +
geom_point(size = 5) +
theme(legend.position = "None") +
xlab(percentage[1]) +
ylab(percentage[2])
p13 <- ggplot(pca_coords, aes(x = PC1, y = PC3, color = binary_groups )) +
p13 <- ggplot(pca_coords, aes(x = PC1, y = PC3, color = binary_groups)) +
geom_point(size = 5) +
theme(legend.position = "bottom") +
xlab(percentage[1]) +
ylab(percentage[3])
p23 <- ggplot(pca_coords, aes(x = PC2, y = PC3, color = binary_groups )) +
p23 <- ggplot(pca_coords, aes(x = PC2, y = PC3, color = binary_groups)) +
geom_point(size = 5) +
theme(legend.position = "None") +
xlab(percentage[2]) +
......
......@@ -24,40 +24,46 @@ message(paste0("[", Sys.time(), "] Configuration done."))
# ================================================================================================
# Functions
# ================================================================================================
#' Function that plots the age distribution (variable Age) of a dataset D, for various
#' Function that plots the age distribution (variable Age) of a dataset d, for various
#' sample categories defined by another variable (provided using split_by).
#'
#' Each age distribution is represented by a boxplot and the jitter points. There is no
#' Each age distribution is represented by a boxplot and the jitter points. There is no
#' return value.
#'
#' @param D The dataset to use for plotting.
#' @param d The dataset to use for plotting.
#' @param split_by The name of thecolkumn to use to split the samples into several categories.
#' @param output_figure_file A string representing the path to the file which will
#' contains the saved plot.
#' @param plot_title The title of the plot, Default to "".
#' @param min_x The minimum value for the y axis. Default to NA (results in the default ggplot
#' @param min_x The minimum value for the y axis. Default to NA (results in the default ggplot
#' behaviour).
#' @param max_x The maximum value for the y axis. Default to NA (results in the default ggplot
#' @param max_x The maximum value for the y axis. Default to NA (results in the default ggplot
#' behaviour).
plot_age_dist <- function(D, split_by, output_figure_file,
plot_age_dist <- function(d, split_by, output_figure_file,
plot_title = "",
min_y = NULL,
max_y = NULL) {
my_palette <- c("#7da7de", "#00599d", "#c2e0ae", "#62a73b")
png(output_figure_file)
myplot <- ggplot(D, aes(x = !!ensym(split_by), y = Age, colour = !!ensym(split_by))) +
myplot <- ggplot(d, aes(x = !!ensym(split_by), y = Age, colour = !!ensym(split_by))) +
geom_boxplot(lwd = 1.2, outlier.shape = NA) +
geom_jitter(size = 3, width = 0.2, height = 0.1) +
geom_jitter(size = 5, width = 0.2, height = 0.1) +
coord_cartesian(ylim = c(min_y, max_y)) +
theme(legend.position = "none",
axis.title.x = element_blank(),
plot.title = element_text(size = 15,
hjust = 0.5),
axis.title.y = element_text(size = 20,
face = "bold"),
axis.text = element_text(size = 20,
face = "bold"),
plot.title = element_text(size = 22,
hjust = 0.5,
face = "bold"),
panel.background = element_blank(),
axis.line = element_line(colour = "black"),
axis.line = element_line(colour = "black", size = 2),
panel.grid.major = element_line(colour = "lightgrey"),
strip.background = element_rect(fill = "black"),
strip.text = element_text(colour = "white")) +
scale_color_brewer(palette = "Dark2") +
scale_color_manual(values = my_palette) +
ggtitle(plot_title)
print(myplot)
dev.off()
......@@ -106,7 +112,7 @@ for (i in seq_len(length(config$datasets))) {
rm(pheno_data_fn)
# We prepare the data for ggplot by adding an extra column (Gender * Disease.status).
D <- pheno_data %>%
d <- pheno_data %>%
dplyr::mutate(gender_disease_status = factor(paste(Gender, Disease.status,
sep = ".")))
message(paste0("[", Sys.time(), "][", dataset_name, "] Data filtered."))
......@@ -145,7 +151,7 @@ for (i in seq_len(length(config$datasets))) {
# We first plot the gender vs age.
output_figure_file <- paste0(output_data_dir, dataset_name, "_agebias_wrt_gender.png")
raad <- round(aads_gd_local, 2)
plot_age_dist(D, "Gender", output_figure_file,
plot_age_dist(d, "Gender", output_figure_file,
plot_title = paste0("[Gender] ", dataset_name, " [AAD=", raad, "]"),
min_y = min_age_across_datasets,
max_y = max_age_across_datasets)
......@@ -155,7 +161,7 @@ for (i in seq_len(length(config$datasets))) {
output_figure_file <- paste0(output_data_dir, dataset_name,
"_agebias_wrt_disease_status.png")
raad <- round(aads_ds_local, 2)
plot_age_dist(D, "Disease.status", output_figure_file,
plot_age_dist(d, "Disease.status", output_figure_file,
plot_title = paste0("[Disease status] ", dataset_name, " [AAD=", raad, "]"),
min_y = min_age_across_datasets,
max_y = max_age_across_datasets)
......@@ -164,17 +170,17 @@ for (i in seq_len(length(config$datasets))) {
# We finally plot the gender * disease status vs age.
output_figure_file <- paste0(output_data_dir, dataset_name,
"_agebias_wrt_gender_and_disease_status.png")
plot_age_dist(D, "gender_disease_status", output_figure_file,
plot_age_dist(d, "gender_disease_status", output_figure_file,
plot_title = paste0("[Gender * Disease status] ", dataset_name),
min_y = min_age_across_datasets,
max_y = max_age_across_datasets)
rm(output_figure_file)
message(paste0("[", Sys.time(), "][", dataset_name, "] Plots created."))
rm(dataset, dataset_name, aads_ds_local, aads_gd_local, pheno_data, D)
rm(dataset, dataset_name, aads_ds_local, aads_gd_local, pheno_data, d)
} # End for each dataset.
rm(i, min_age_across_datasets, max_age_across_datasets)
# Summary plot of the Average Age Differences for all datasets and the two
# Summary plot of the Average Age Differences for all datasets and the two
# comparisons of interest.
summary_plot_filename <- paste0(output_data_dir, "Average_age_differences.png")
png(summary_plot_filename)
......@@ -185,16 +191,17 @@ plot(x = c(1, length(aads_ds_values)),
xlab = "",
ylab = "",
xaxt = "n", font = 2, cex.axis = 1.5, cex.main = 1.5)
mtext("Average age difference", side=2, line=3, cex=1.5, font = 2)
axis(side = 1,
las = 2,
labels = aads_datasets,
at = seq(1, length(aads_ds_values)))
lines(x = c(0, 1 + length(aads_ds_values)),
y = c(2, 2),
lty = 5,
lwd = 2,
col = "darkgrey")
mtext("Average age difference", side = 2, line = 3, cex = 1.5, font = 2)
mtext("Datasets", side = 1, line = 1, cex = 1.5, font = 2)
# axis(side = 1,
# las = 2,
# labels = aads_datasets,
# at = seq(1, length(aads_ds_values)))
# lines(x = c(0, 1 + length(aads_ds_values)),
# y = c(2, 2),
# lty = 5,
# lwd = 2,
# col = "darkgrey")
lines(x = c(0, 1 + length(aads_ds_values)),
y = c(5, 5),
lty = 5,
......
#!/usr/bin/env Rscript
# ================================================================================================
# Libraries
# ================================================================================================
library("yaml")
library("readr")
library("tidyverse")
library("ArrayUtils")
source("../libs/conf/confR.R")
source("../libs/utils/utils.R")
message(paste0("[", Sys.time(), "] Libraries loaded."))
# ================================================================================================
# Configuration