diff --git a/DESCRIPTION b/DESCRIPTION
index b97df0c..e28eace 100644
--- a/DESCRIPTION
+++ b/DESCRIPTION
@@ -5,7 +5,8 @@ Version: 0.99.3
Date: 2021-03-16
Authors@R: c(
person(given = "Arsenij", family = "Ustjanzew", email = "arsenij.ustjanzew@gmail.com", role = c("aut", "cre", "cph"), comment = c(ORCID = "0000-0002-1014-4521")),
- person("Federico", "Marini", role = "aut", email = "marinif@uni-mainz.de", comment = c(ORCID = '0000-0003-3252-7758')))
+ person("Federico", "Marini", role = "aut", email = "marinif@uni-mainz.de", comment = c(ORCID = '0000-0003-3252-7758')),
+ person(given = "Charlotte", family = "Reuschel", email = "charlotte.reuschel@gmx.de", role = "aut", comment = c(ORCID = "0000-0003-2722-279X")))
Description: This R package provides an R Shiny application that enables the user to generate,
manage, and edit data and metadata files suitable for the import in cBioPortal for Cancer Genomics.
Create cancer studies and edit its metadata. Upload mutation data of a patient that will be concatenated to the data_mutation_extended.txt file of the study.
diff --git a/NAMESPACE b/NAMESPACE
index 0d70b5a..23cc1cb 100644
--- a/NAMESPACE
+++ b/NAMESPACE
@@ -14,6 +14,7 @@ importFrom(basilisk,basiliskStart)
importFrom(basilisk,basiliskStop)
importFrom(dplyr,bind_rows)
importFrom(dplyr,mutate)
+importFrom(htmltools,HTML)
importFrom(htmltools,tagList)
importFrom(jsonlite,fromJSON)
importFrom(magrittr,"%<>%")
@@ -52,6 +53,7 @@ importFrom(shiny,selectInput)
importFrom(shiny,shinyApp)
importFrom(shiny,showModal)
importFrom(shiny,showNotification)
+importFrom(shiny,splitLayout)
importFrom(shiny,tags)
importFrom(shiny,textInput)
importFrom(shiny,uiOutput)
diff --git a/R/cbpManager-pkg.R b/R/cbpManager-pkg.R
index fa50df2..38c5347 100644
--- a/R/cbpManager-pkg.R
+++ b/R/cbpManager-pkg.R
@@ -6,7 +6,7 @@
#' @author Arsenij Ustjanzew \email{arsenij.ustjanzew@@gmail.com}
#'
#' @importFrom magrittr %>% %<>%
-#' @importFrom shiny actionButton column dateInput fluidRow icon invalidateLater
+#' @importFrom shiny actionButton column dateInput fluidRow icon invalidateLater splitLayout
#' modalButton modalDialog NS numericInput observeEvent reactive reactiveValues
#' reactiveValuesToList removeModal renderText renderUI runApp selectInput
#' shinyApp showModal showNotification textInput uiOutput updateSelectInput
@@ -17,7 +17,7 @@
#' @importFrom dplyr bind_rows mutate
#' @importFrom jsonlite fromJSON
#' @importFrom vroom vroom
-#' @importFrom htmltools tagList
+#' @importFrom htmltools tagList HTML
#' @importFrom shinydashboard box dashboardBody dashboardHeader dashboardPage
#' dashboardSidebar menuItem sidebarMenu tabBox tabItem tabItems
#' @importFrom DT renderDT styleEqual DTOutput datatable formatStyle renderDataTable
diff --git a/R/functions.R b/R/functions.R
index 6461525..81649bf 100644
--- a/R/functions.R
+++ b/R/functions.R
@@ -534,3 +534,30 @@ Please try reinstalling cbpManager and basilisk or contact the support at https:
}
})
}
+
+#' Read a metafile line by line into a data frame.
+#'
+#' @param filepath Filepath with filename of metafile.
+#' @return data.frame
+#' @examples
+#' cbpManager:::read_meta(system.file("study", "testpatient", "meta_CNA.txt", package = "cbpManager"))
+#'
+read_meta <- function(filepath) {
+ meta_df <- data.frame(attribute = character(), value = character())
+ con = file(filepath, "r")
+ while (TRUE) {
+ line = readLines(con, n = 1)
+ if (length(line) == 0) {
+ break
+ }
+ splited_line <- stringr::str_split(line, ": ", n = 2)
+ meta_df <-
+ rbind(meta_df,
+ list(
+ attribute = splited_line[[1]][1],
+ value = splited_line[[1]][2])
+ )
+ }
+ close(con)
+ return(meta_df)
+}
diff --git a/R/global.R b/R/global.R
index 7ef37ae..89b81e9 100644
--- a/R/global.R
+++ b/R/global.R
@@ -3,6 +3,7 @@ source(system.file("tabs", "studyTab.R", package = "cbpManager"), local = TRUE)
source(system.file("tabs", "patientTab.R", package = "cbpManager"), local = TRUE)
source(system.file("tabs", "sampleTab.R", package = "cbpManager"), local = TRUE)
source(system.file("tabs", "mutationsTab.R", package = "cbpManager"), local = TRUE)
+source(system.file("tabs", "cnaTab.R", package = "cbpManager"), local = TRUE)
source(system.file("tabs", "timelineTab.R", package = "cbpManager"), local = TRUE)
source(system.file("tabs", "resourceTab.R", package = "cbpManager"), local = TRUE)
source(system.file("tabs", "validationTab.R", package = "cbpManager"), local = TRUE)
diff --git a/R/shinyAppServer.R b/R/shinyAppServer.R
index 79a385c..f46336d 100644
--- a/R/shinyAppServer.R
+++ b/R/shinyAppServer.R
@@ -112,10 +112,12 @@ shinyAppServer <- function(input, output, session) {
source(system.file("reactives", "reactivesSampleTab.R", package = "cbpManager"), local = TRUE)
# Tab 4 Mutations ---------------------------------------------------------------
source(system.file("reactives", "reactivesMutationsTab.R", package = "cbpManager"), local = TRUE)
- # Tab 5 Timelines ---------------------------------------------------------------
+ # Tab 5 Copy Number Data ---------------------------------------------------------
+ source(system.file("reactives", "reactivesCnaTab.R", package = "cbpManager"), local = TRUE)
+ # Tab 6 Timelines ---------------------------------------------------------------
source(system.file("reactives", "reactivesTimelineTab.R", package = "cbpManager"), local = TRUE)
- # Tab 6 Resource data ---------------------------------------------------------------
+ # Tab 7 Resource data ---------------------------------------------------------------
source(system.file("reactives", "reactivesResourceTab.R", package = "cbpManager"), local=TRUE)
- # Tab 7 Validation ---------------------------------------------------------------
+ # Tab 8 Validation ---------------------------------------------------------------
source(system.file("reactives", "reactivesValidationTab.R", package = "cbpManager"), local=TRUE)
}
diff --git a/R/shinyAppUI.R b/R/shinyAppUI.R
index 977860a..4d1bee9 100644
--- a/R/shinyAppUI.R
+++ b/R/shinyAppUI.R
@@ -60,6 +60,7 @@ shinyAppUI <- dashboardPage(
menuItem("Patient", tabName = "patient"),
menuItem("Sample", tabName = "sample"),
menuItem("Mutations", tabName = "mutations"),
+ menuItem("Copy Number Data", tabName = "cna"),
menuItem("Timelines", tabName = "timelines"),
menuItem("Resources", tabName = "resource"),
menuItem("Validation", tabName = "validation")
@@ -98,6 +99,9 @@ shinyAppUI <- dashboardPage(
# Tab 4 Mutations - mutationsTab.R
mutationsTab,
+
+ # Tab Copy Number Data - cnaTab.R
+ cnaTab,
# Tab 5 Timelines - timelineTab.R
timelineTab,
diff --git a/inst/apphelp/descriptionCnaTab.md b/inst/apphelp/descriptionCnaTab.md
new file mode 100644
index 0000000..cba10fa
--- /dev/null
+++ b/inst/apphelp/descriptionCnaTab.md
@@ -0,0 +1,23 @@
+**Load a valid copy number data file.** This file is used in cBioPortal for the copy number data panel (see image on the right.)
+
+---
+
+#### Description of a valid copy number alteration data file:
+
+The user can currently upload the file **"all_thresholded.by_genes.txt"** derived from GISTIC 2.0 or a **tab-separated file** containing the following columns:
+
+One or both of:
+
+- **Hugo_Symbol (Required)**: A HUGO gene symbol.
+- **Entrez_Gene_Id (Optional, but recommended)**: An Entrez Gene identifier.
+
+**For each sample in the dataset an additional column is required using the sample ID as column header.** Please make sure that all of the sample IDs have been added to the loaded study via the Sample tab before upload the file.
+
+The discrete copy number data file contains for each gene-sample combination a copy number level. By default the following applies:
+- "-2" is a deep loss, possibly a homozygous deletion
+- "-1" is a single-copy loss (heterozygous deletion)
+- "0" is diploid
+- "1" indicates a low-level gain
+- "2" is a high-level amplification
+
+The information "profile_name" and "profile_description" listed in the metafile can be adapted to the uploaded file (see "Change metadata of copy number alteration" below). It is recommended to provide the source and a brief characterization of the data under "profile_name" and to define the interpretation of the copy number level in the "profile_description".
\ No newline at end of file
diff --git a/inst/apphelp/tour_cna.txt b/inst/apphelp/tour_cna.txt
new file mode 100644
index 0000000..2098958
--- /dev/null
+++ b/inst/apphelp/tour_cna.txt
@@ -0,0 +1,9 @@
+element;intro
+#Welcome;Welcome to the interactive tour for cbpManager!
In the Copy Number Data tab, you can add copy number alteration data to samples by uploading a file in the appropriate format. In the following you will learn how to do this in detail.
+#cna_description;This box contains a description of the Copy Number Data tab.
+#cna_img;Here you can see an example image how the copy number data will look later in cBioPortal.
+#cna_metadata; Here you have the opportunity of changing the information that is saved in the metafile of the copy number data under "profile_name" and "profile_description". Please refer to the description above for more information.
+#CNAdata;If the loaded study already has copy number data, it would be shown in this table.
+#chooseCNADiv;Upload a copy number data file to the study. This file will be concatenated to the existing copy number data. Please have a look at the description box for the correct file format! If the upload was successful, the new copy number data is added to the table on the right.
+#saveCNA;Make the changes persistent by saving the file!
+#Thanks;Thank you for taking the Copy Number Data tab tour of cbpManager!
\ No newline at end of file
diff --git a/inst/reactives/reactivesCnaTab.R b/inst/reactives/reactivesCnaTab.R
new file mode 100644
index 0000000..5d16d23
--- /dev/null
+++ b/inst/reactives/reactivesCnaTab.R
@@ -0,0 +1,438 @@
+# image ---------------------------------------------------------------
+output$CopyNumberDataImg <- renderImage(
+ {
+ return(
+ list(
+ src = system.file("www", "cna-data.PNG", package = "cbpManager"),
+ contentType = "image/png",
+ alt = "annotation-example",
+ width = "auto"
+ )
+ )
+ },
+ deleteFile = FALSE
+)
+
+# tour ---------------------------------------------------------------
+observeEvent(input$tour_cna, {
+ tour <- read.delim(system.file("apphelp", "tour_cna.txt", package = "cbpManager"),
+ sep = ";", stringsAsFactors = FALSE,
+ row.names = NULL, quote = "")
+ rintrojs::introjs(session, options = list(steps = tour))
+})
+
+# show table ---------------------------------------------------------------
+output$CNAdata <- DT::renderDT({
+ if (!is.null(loadedData$studyID)) {
+ DT::datatable(loadedData$data_cna,
+ options = list(scrollX = TRUE))
+ }
+})
+
+# profile_name and profile_description -----------------------------------------------------------
+observeEvent(input$saveMetadata, {
+ if(is.null(loadedData$studyID)){
+ showNotification(
+ "Please select and load a study in the 'Study' tab.",
+ type = "error",
+ duration = NULL
+ )
+ } else {
+ if (!rapportools::is.empty(input$cna_profile_name)) {
+ loadedData$meta_cna[which(loadedData$meta_cna$attribute=="profile_name"),]$value <- input$cna_profile_name
+ }
+ if (!rapportools::is.empty(input$cna_profile_description)) {
+ loadedData$meta_cna[which(loadedData$meta_cna$attribute=="profile_description"),]$value <- input$cna_profile_description
+ }
+
+ # create meta_cna data.frame
+ #meta_cna_df <- loadedData$meta_cna
+
+ # write meta_CNA.txt
+ write.table(
+ loadedData$meta_cna,
+ file.path(study_dir, loadedData$studyID, "meta_CNA.txt.temp"),
+ append = FALSE,
+ sep = ": ",
+ row.names = FALSE,
+ col.names = FALSE,
+ quote = FALSE
+ )
+ file.rename(
+ file.path(study_dir, loadedData$studyID, "meta_CNA.txt.temp"),
+ file.path(study_dir, loadedData$studyID, "meta_CNA.txt")
+ )
+
+ # logging
+ if (!is.null(logDir)) {
+ writeLogfile(
+ outdir = logDir,
+ modified_file = file.path(loadedData$studyID, "meta_CNA.txt")
+ )
+ }
+
+ showNotification(paste0("File meta_CNA.txt of study ", loadedData$studyID, " updated successfully!"),
+ type = "message",
+ duration = 10
+ )
+ removeModal()
+ }
+})
+
+output$curr_profile_name <- renderText({
+ req(loadedData$meta_cna)
+ prof_name <- loadedData$meta_cna[which(loadedData$meta_cna$attribute=="profile_name"),]$value
+ if(!is.na(prof_name)){
+ prof_name
+ } else {
+ "No profile name."
+ }
+})
+
+output$curr_profile_description <- renderText({
+ req(loadedData$meta_cna)
+ prof_desc <- loadedData$meta_cna[which(loadedData$meta_cna$attribute=="profile_description"),]$value
+ if(!is.na(prof_desc)){
+ prof_desc
+ } else {
+ "No profile description."
+ }
+})
+
+# upload file ---------------------------------------------------------------------------------
+
+# ui of modal dialog in case of negative values in Entrez_Gene_Id column
+dataModal <- function(failed = FALSE) {
+ modalDialog(
+ title = "Warning",
+ "Negative values in the Locus ID/Entrez_Gene_Id column will prevent the data from being
+ uploaded to cBioPortal. Choose one of the following options.",
+ radioButtons(
+ "options",
+ label = "Choose an option to continue:",
+ choices = list(
+ "Delete rows with negative values and merge data (recommended)" = 1,
+ "Keep all data and merge despite negative values" = 2,
+ "Cancel file upload" = 3
+ ),
+ selected = 1
+ ),
+
+ footer = tagList(actionButton("ok", "OK")
+ )
+ )
+}
+
+# initiate reactive objects
+uploaded_data <- reactiveValues(df = NULL)
+validated_data <- reactiveValues(df = NULL)
+
+# management of file upload
+observeEvent(input$chooseCNA, {
+
+ output$CNAdata <- DT::renderDT({
+ if (!is.null(loadedData$studyID)) {
+ DT::datatable(loadedData$data_cna,
+ options = list(scrollX = TRUE))
+ }
+ })
+
+ # check if a study is loaded
+ loaded <- NULL
+ if (is.null(loadedData$studyID)) {
+ loaded = FALSE
+ showNotification(
+ "Please select and load a study in the 'Study' tab.",
+ type = "error",
+ duration = NULL
+ )
+ # return(NULL)
+ } else {
+ loaded = TRUE
+ }
+
+ # if a study is loaded, access respective samples and cna data
+ if (loaded == TRUE) {
+ uploaded_data$df <- loadedData$data_cna
+
+ cases_samples <-
+ loadedData$data_clinical_sample[4:nrow(loadedData$data_clinical_sample), "SAMPLE_ID"]
+ }
+
+ # check file format before upload
+ if (!grepl("\\.[txt|tsv]", input$chooseCNA$name)) {
+ showNotification(
+ "The file format is not supported.
+ File should be '.txt', '.tsv'.",
+ type = "error",
+ duration = NULL
+ )
+ } else {
+ uploaded_data$df <-
+ as.data.frame(vroom::vroom(input$chooseCNA$datapath, delim = "\t"))
+
+ if ("Hugo_Symbol" %in% colnames(uploaded_data$df)) {
+ requiredCols <- "Hugo_Symbol" # upload of any .txt file
+ } else {
+ requiredCols <- "Gene Symbol" # upload of GISTIC output
+ }
+
+ # check presence of required columns before renaming/deleting columns
+ if (any(!requiredCols %in% colnames(uploaded_data$df))) {
+ showNotification(
+ "One or more of the required columns are missing.",
+ type = "error",
+ duration = NULL
+ )
+ } else {
+ # adjustments when GISTIC output is uploaded
+ colnames(uploaded_data$df)[which(names(uploaded_data$df) == "Gene Symbol")] <-
+ "Hugo_Symbol"
+ colnames(uploaded_data$df)[which(names(uploaded_data$df) == "Locus ID")] <-
+ "Entrez_Gene_Id"
+ uploaded_data$df$Cytoband <- NULL
+ }
+ }
+
+ # check if all sample IDs have been added to the loaded study
+ added <- NULL
+ if (loaded == TRUE) {
+ if (any(!colnames(uploaded_data$df)[3:ncol(uploaded_data$df)] %in% cases_samples)) {
+ added = FALSE
+ showNotification(
+ "Please enter all sample IDs in the 'Sample' tab before proceeding.",
+ type = "error",
+ duration = NULL
+ )
+ } else {
+ added = TRUE
+ }
+ }
+
+ if (loaded == TRUE && added == TRUE) {
+ validated_data$df <- loadedData$data_cna
+
+ # if study is loaded and all samples are added, show data of uploaded file in table
+ output$CNAdata <- DT::renderDT({
+ DT::datatable(uploaded_data$df,
+ options = list(scrollX = TRUE))
+ })
+ }
+
+ # check if there is a negative value in the column "Entrez_Gene_Id"
+ neg <- NULL
+ if ("Entrez_Gene_Id" %in% colnames(uploaded_data$df)) {
+ for (i in 2:nrow(uploaded_data$df)) {
+ if (uploaded_data$df$Entrez_Gene_Id[i] < 0) {
+ neg = TRUE
+ break
+ } else {
+ neg = FALSE
+ }
+ }
+ } else {
+ neg = FALSE
+ }
+
+ # in case of a negative value show a modal dialog with three options
+ if (loaded == TRUE && added == TRUE && neg == TRUE) {
+ showModal(dataModal())
+ } else if (loaded == TRUE && added == TRUE && neg == FALSE) {
+ uploaded_data$df <- merge(uploaded_data$df, loadedData$data_cna, all = TRUE)
+ validated_data$df <- uploaded_data$df
+
+ # reset
+ loaded <- NULL
+ added <- NULL
+ neg <- NULL
+ }
+})
+
+# completion of the file upload depending on the option selected
+observeEvent(input$ok, {
+ if (input$options == "1") {
+ uploaded_data$df <- uploaded_data$df[uploaded_data$df$Entrez_Gene_Id > -1,]
+ neg = FALSE
+ removeModal()
+ } else if (input$options == "2") {
+ neg = FALSE
+ removeModal()
+ } else if (input$options == "3") {
+ showNotification(
+ "The upload of a copy number data file was canceled.",
+ type = "message",
+ duration = NULL
+ )
+ output$CNAdata <- DT::renderDT({
+ DT::datatable(loadedData$data_cna,
+ options = list(scrollX = TRUE))
+ })
+ validated_data$df <- NULL
+ neg = TRUE
+ removeModal()
+ }
+
+ if (neg == FALSE) {
+ uploaded_data$df <- merge(uploaded_data$df, loadedData$data_cna, all = TRUE)
+ validated_data$df <- uploaded_data$df
+
+ # reset
+ loaded <- NULL
+ added <- NULL
+ neg <- NULL
+ }
+})
+
+# save data ---------------------------------------------------------------
+observeEvent(input$saveCNA, {
+ if(is.null(loadedData$studyID)) {
+ showNotification(
+ "Please select and load a study in the 'Study' tab.",
+ type = "error",
+ duration = NULL
+ )
+ }
+
+ if (!is.null(validated_data$df)) {
+ validated_data$df$Entrez_Gene_Id[is.na(validated_data$df$Entrez_Gene_Id)] <- ""
+
+ if ("Entrez_Gene_Id" %in% colnames(validated_data$df)) {
+ validated_data$df <-
+ validated_data$df %>% dplyr::select(Hugo_Symbol, Entrez_Gene_Id, everything())
+ }
+
+ loadedData$data_cna <- validated_data$df
+ showNotification("Copy number data file submitted successfully!",
+ type = "message",
+ duration = 10
+ )
+ output$CNAdata <- DT::renderDT({
+ if (!is.null(loadedData$studyID)) {
+ DT::datatable(loadedData$data_cna,
+ options = list(scrollX = TRUE))
+ }
+ })
+ # reset
+ validated_data$df <- NULL
+ } else {
+ showNotification(
+ "Please upload a file.",
+ type = "error",
+ duration = NULL
+ )
+ }
+
+ req(loadedData$studyID, loadedData$data_cna, loadedData$data_cna_filename)
+ write.table(
+ loadedData$data_cna,
+ file.path(study_dir, loadedData$studyID, paste0(loadedData$data_cna_filename, ".temp")),
+ append = FALSE,
+ sep = "\t",
+ row.names = FALSE,
+ col.names = TRUE,
+ quote = FALSE
+ )
+ file.rename(
+ file.path(study_dir, loadedData$studyID, paste0(loadedData$data_cna_filename, ".temp")),
+ file.path(study_dir, loadedData$studyID, loadedData$data_cna_filename)
+ )
+
+ # logging
+ if (!is.null(logDir)) {
+ writeLogfile(
+ outdir = logDir,
+ modified_file = file.path(loadedData$studyID, loadedData$data_cna_filename)
+ )
+ }
+
+ # add cases_cna
+ case_list_dir <-
+ file.path(study_dir, loadedData$studyID, "case_lists")
+ if (!dir.exists(case_list_dir)) dir.create(case_list_dir)
+ cases_samples <-
+ loadedData$data_clinical_sample[4:nrow(loadedData$data_clinical_sample), "SAMPLE_ID"]
+ cases_cna_df <-
+ data.frame(
+ V1 = c(
+ "cancer_study_identifier",
+ "stable_id",
+ "case_list_category",
+ "case_list_name",
+ "case_list_description",
+ "case_list_ids"
+ ),
+ V2 = c(
+ loadedData$studyID,
+ paste0(loadedData$studyID, "_cna"),
+ "all_cases_with_cna_data",
+ "Samples with CNA data",
+ paste0(
+ "All samples with CNA data (",
+ nrow(loadedData$data_clinical_sample) - 3,
+ " samples)"
+ ),
+ paste(cases_samples, collapse = "\t")
+ )
+ )
+ write.table(
+ cases_cna_df,
+ file.path(case_list_dir, "cases_cna.txt.temp"),
+ append = FALSE,
+ sep = ": ",
+ row.names = FALSE,
+ col.names = FALSE,
+ quote = FALSE
+ )
+ file.rename(
+ file.path(case_list_dir, "cases_cna.txt.temp"),
+ file.path(case_list_dir, "cases_cna.txt")
+ )
+
+ # meta_CNA
+ if (!file.exists(file.path(study_dir, loadedData$studyID, "meta_CNA.txt"))) {
+ meta_cna_df <-
+ data.frame(
+ V1 = c(
+ "cancer_study_identifier",
+ "genetic_alteration_type",
+ "datatype",
+ "stable_id",
+ "show_profile_in_analysis_tab",
+ "profile_name",
+ "profile_description",
+ "data_filename"
+ ),
+ V2 = c(
+ loadedData$studyID,
+ "COPY_NUMBER_ALTERATION",
+ "DISCRETE",
+ paste0(loadedData$studyID, "_cna"),
+ "true",
+ loadedData$meta_cna[which(loadedData$meta_cna$attribute=="profile_name"),]$value,
+ loadedData$meta_cna[which(loadedData$meta_cna$attribute=="profile_description"),]$value,
+ loadedData$data_cna_filename
+ )
+ )
+ write.table(
+ meta_cna_df,
+ file.path(study_dir, loadedData$studyID, "meta_CNA.txt.temp"),
+ append = FALSE,
+ sep = ": ",
+ row.names = FALSE,
+ col.names = FALSE,
+ quote = FALSE
+ )
+ file.rename(
+ file.path(study_dir, loadedData$studyID, "meta_CNA.txt.temp"),
+ file.path(study_dir, loadedData$studyID, "meta_CNA.txt")
+ )
+ }
+
+ # logging
+ if (!is.null(logDir)) {
+ writeLogfile(
+ outdir = logDir,
+ modified_file = file.path(loadedData$studyID, "meta_CNA.txt")
+ )
+ }
+})
\ No newline at end of file
diff --git a/inst/reactives/reactivesStudyTab.R b/inst/reactives/reactivesStudyTab.R
index 82fddcf..f249c32 100644
--- a/inst/reactives/reactivesStudyTab.R
+++ b/inst/reactives/reactivesStudyTab.R
@@ -281,6 +281,23 @@ observeEvent(input$upload, {
Variant_Classification = character(),
HGVSp_Short = character()
)
+ loadedData$data_cna_filename <- "data_CNA.txt"
+ loadedData$meta_cna <- loadedData$meta_cna <- data.frame(
+ attribute = c(
+ "cancer_study_identifier",
+ "genetic_alteration_type",
+ "datatype",
+ "stable_id",
+ "show_profile_in_analysis_tab",
+ "profile_name",
+ "profile_description",
+ "data_filename"
+ ),
+ value = rep(NA, 8)
+ )
+ loadedData$data_cna <- data.frame(
+ Hugo_Symbol = character()
+ )
loadedData$data_timeline_treatment <- data.frame(
PATIENT_ID = character(),
START_DATE = numeric(),
@@ -413,6 +430,34 @@ observeEvent(input$upload, {
)
loadedData$data_mutations_extended <- data_mutations_extended
}
+
+ # read data_cna ---------------------------------------------------------------
+ meta_cna <-
+ file.path(study_dir, loadedData$studyID, "meta_CNA.txt")
+ if (file.exists(meta_cna)) {
+ loadedData$meta_cna <- read_meta(meta_cna)
+ loadedData$data_cna_filename <- loadedData$meta_cna[which(loadedData$meta_cna$attribute=="data_filename"),]$value
+ }
+
+ data_cna_file <-
+ file.path(
+ study_dir,
+ loadedData$studyID,
+ loadedData$data_cna_filename
+ )
+ if (file.exists(data_cna_file)) {
+ data_cna <-
+ read.table(data_cna_file,
+ sep = "\t",
+ header = TRUE,
+ comment.char = "#",
+ stringsAsFactors = FALSE,
+ quote = "",
+ fill = FALSE,
+ check.names = FALSE
+ )
+ loadedData$data_cna <- data_cna
+ }
# read data_timeline_treatment ---------------------------------------------------------------
data_timeline_treatment_file <-
diff --git a/inst/study/testpatient/case_lists/cases_cna.txt b/inst/study/testpatient/case_lists/cases_cna.txt
new file mode 100644
index 0000000..9123546
--- /dev/null
+++ b/inst/study/testpatient/case_lists/cases_cna.txt
@@ -0,0 +1,6 @@
+cancer_study_identifier: testpatient
+stable_id: testpatient_cna
+case_list_category: all_cases_with_cna_data
+case_list_name: Samples with CNA data
+case_list_description: All samples with CNA data (2 samples)
+case_list_ids: Testpatient_01 Testpatient_02
\ No newline at end of file
diff --git a/inst/study/testpatient/data_CNA.txt b/inst/study/testpatient/data_CNA.txt
new file mode 100644
index 0000000..14cfc3c
--- /dev/null
+++ b/inst/study/testpatient/data_CNA.txt
@@ -0,0 +1,4 @@
+Hugo_Symbol Testpatient_01 Testpatient_02
+MET 0 1
+ATM -1 0
+ERBB2 2 0
\ No newline at end of file
diff --git a/inst/study/testpatient/meta_CNA.txt b/inst/study/testpatient/meta_CNA.txt
new file mode 100644
index 0000000..0f60c35
--- /dev/null
+++ b/inst/study/testpatient/meta_CNA.txt
@@ -0,0 +1,8 @@
+cancer_study_identifier: testpatient
+genetic_alteration_type: COPY_NUMBER_ALTERATION
+datatype: DISCRETE
+stable_id: gistic
+show_profile_in_analysis_tab: true
+profile_name: Putative copy-number alterations from GISTIC
+profile_description: Putative copy-number from GISTIC 2.0. Values: -2 = homozygous deletion; -1 = hemizygous deletion; 0 = neutral / no change; 1 = gain; 2 = high level amplification.
+data_filename: data_CNA.txt
\ No newline at end of file
diff --git a/inst/tabs/cnaTab.R b/inst/tabs/cnaTab.R
new file mode 100644
index 0000000..a8b72f6
--- /dev/null
+++ b/inst/tabs/cnaTab.R
@@ -0,0 +1,131 @@
+cnaTab <- tabItem(
+ tabName = "cna",
+ div(style="display:inline-block",h2("Copy Number Data")),
+ div(style="display:inline-block; padding-bottom:15px; margin-left:30px",bsButton(
+ "tour_cna",
+ label = "Tour",
+ icon = icon("question"),
+ style = "info",
+ size = "extra-small"
+ )),
+ fluidRow(
+ width = 12,
+ column(
+ width = 6,
+ id = "cna_description",
+ box(
+ title = "Description",
+ collapsible = TRUE,
+ collapsed = TRUE,
+ solidHeader = TRUE,
+ includeMarkdown(system.file("apphelp", "descriptionCnaTab.md", package = "cbpManager")),
+ width = NULL
+ )
+ ),
+ column(
+ width = 6,
+ id = "cna_img",
+ box(
+ title = "Sample from cBioPortal",
+ collapsible = TRUE,
+ collapsed = FALSE,
+ solidHeader = TRUE,
+ tags$head(
+ tags$style(
+ type = "text/css",
+ "#CopyNumberDataImg img {max-width: 100%; width: 100%; height: auto}"
+ )
+ ),
+ imageOutput(
+ "CopyNumberDataImg",
+ height = "auto"
+ ),
+ width = NULL
+ )
+ )
+ ),
+ fluidRow(
+ tags$head(
+ tags$style(HTML('#q8, #q9{margin-top: 24px}'))
+ ),
+ width = 12,
+ column(
+ width = 12,
+ id = "cna_metadata",
+ box(
+ title = "Change metadata of copy number alteration",
+ collapsible = TRUE,
+ collapsed = TRUE,
+ solidHeader = TRUE,
+ width = NULL,
+ column(
+ 6,
+ splitLayout(
+ cellWidths = c("93%", "7%"),
+ textInput(inputId = "cna_profile_name", label = "Change profile name:"),
+ popify(
+ bsButton(
+ "q8",
+ label = "",
+ icon = icon("question"),
+ style = "info",
+ size = "extra-small"
+ ),
+ "Profile name",
+ "A name for the discrete copy number data, e.g. Putative copy-number alterations from GISTIC."
+ )
+ ),
+ splitLayout(
+ cellWidths = c("93%", "7%"),
+ textInput(inputId = "cna_profile_description", label = "Change profile description:"),
+ popify(
+ bsButton(
+ "q9",
+ label = "",
+ icon = icon("question"),
+ style = "info",
+ size = "extra-small"
+ ),
+ "Profile description",
+ "A description of the copy number data."
+ )
+ ),
+ actionButton("saveMetadata", "Save metadata", class = "btn-success")
+ ),
+ column(
+ 6,
+ htmltools::HTML(""),
+ verbatimTextOutput("curr_profile_name"),
+
+ htmltools::HTML(""),
+ verbatimTextOutput("curr_profile_description")
+ )
+ )
+ )
+ ),
+
+ fluidRow(
+ width = 12,
+ box(
+ column(
+ 3,
+ div(id = "chooseCNADiv",
+ fileInput("chooseCNA", "Choose Copy Number Data File",
+ multiple = FALSE,
+ accept = c(
+ "text/tsv",
+ "text/tab-separated-values,text/plain",
+ ".tsv", ".txt"
+ )
+ )
+ ),
+ actionButton("saveCNA", "Save file", class = "btn-success")
+ ),
+ column(
+ 9,
+ DT::DTOutput("CNAdata")
+ ),
+ width = 12
+ )
+ )
+)
diff --git a/inst/www/cna-data.png b/inst/www/cna-data.png
new file mode 100644
index 0000000..5a9473b
Binary files /dev/null and b/inst/www/cna-data.png differ
diff --git a/man/read_meta.Rd b/man/read_meta.Rd
new file mode 100644
index 0000000..8533cd2
--- /dev/null
+++ b/man/read_meta.Rd
@@ -0,0 +1,21 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/functions.R
+\name{read_meta}
+\alias{read_meta}
+\title{Read a metafile line by line into a data frame.}
+\usage{
+read_meta(filepath)
+}
+\arguments{
+\item{filepath}{Filepath with filename of metafile.}
+}
+\value{
+data.frame
+}
+\description{
+Read a metafile line by line into a data frame.
+}
+\examples{
+cbpManager:::read_meta(system.file("study", "testpatient", "meta_CNA.txt", package = "cbpManager"))
+
+}
diff --git a/vignettes/images/20.png b/vignettes/images/20.png
new file mode 100644
index 0000000..71a9df6
Binary files /dev/null and b/vignettes/images/20.png differ
diff --git a/vignettes/intro.rmd b/vignettes/intro.rmd
index 1562050..972850f 100644
--- a/vignettes/intro.rmd
+++ b/vignettes/intro.rmd
@@ -239,7 +239,15 @@ knitr::include_graphics(file.path("images/13.PNG"))
### Mutation data (MAF):
-The "Mutations" page offers the user the possibility to upload MAF files. If mutation data is already available, the content of the MAF file will be concatinated to the already existing data, taking into account the columns. The MAF file must meet certain requirements, i.e. contain specific columns (see [link](https://docs.cbioportal.org/5.1-data-loading/data-loading/file-formats#data-file-5)). Similarly, the changes must be finalized by saving.
+The "Mutations" page offers the user the possibility to upload MAF files. If mutation data is already available, the content of the MAF file will be concatenated to the already existing data, taking into account the columns. The MAF file must meet certain requirements, i.e. contain specific columns (see [link](https://docs.cbioportal.org/5.1-data-loading/data-loading/file-formats#data-file-5)). Similarly, the changes must be finalized by saving.
+
+```{r, out.width="100%", echo=FALSE}
+knitr::include_graphics(file.path("images/20.PNG"))
+```
+
+### Copy number alteration (CNA):
+
+The "Copy Number Data" page offers the user the possibility to upload a file containing information about copy number alterations (CNA) of genes. If CNA data is already available, the content of the uploaded file will be concatenated to the already existing data, taking into account the rows and columns. The uploaded file must meet certain requirements, i.e. contain specific columns (see the example described [here](https://docs.cbioportal.org/5.1-data-loading/data-loading/file-formats#data-file-1)). Alternatively to a tab-separated file, meeting these requirements, the output file "all_thresholded.by_genes.txt" derived from GISTIC 2.0 can be uploaded directly. If the file upload was successful (without any error messages), you can see the preview of the resulting file in the table on the right. In the preview table the content of the file is combined with already existing data. **To generate the required study files and make the changes permanent, you need to click on the "Save file" button.**
```{r, out.width="100%", echo=FALSE}
knitr::include_graphics(file.path("images/14.PNG"))