diff --git a/.gitignore b/.gitignore index 5448064..9c4da00 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ .DS_Store .quarto # folders +exampledata/ fastqs/ bams/ fastq_files/ @@ -17,12 +18,4 @@ countmatrices/ datasets/T8/ datasets/Tox/ # R files -R/steps_2_create_pkg.R -R/apptest.R -R/appglue.R -R/countingT8.R -R/counting.R -R/countingbase.R -R/countingall.R -R/shinyselect_michael.R -R/app_v1.R +R/2023-11-07-Analysis-UWB-zeros-removed-GGiner copy.Rmd diff --git a/NAMESPACE b/NAMESPACE index 6ae9268..359218e 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -1,2 +1,11 @@ -# Generated by roxygen2: do not edit by hand +# Import the entire shiny and DT packages +import(shiny) +import(DT) +# Import specific functions from other packages +importFrom(stats, rnorm, runif) # Example functions from stats (if used) +importFrom(utils, read.csv, globalVariables) # For file reading or declaring global variables + +# Declare global variables to avoid warnings during R CMD check +globalVariables(c("reactiveVal", "renderPlot", "renderDataTable", + "dataTableOutput", "textInput", "datatable")) diff --git a/R/app.R b/R/app.R index 9503d57..65f96ec 100644 --- a/R/app.R +++ b/R/app.R @@ -3,138 +3,181 @@ source("global.R") global_dge <- NULL # Define UI -ui <- navbarPage("CuReSPR", id = "main", theme = shinytheme("cerulean"), - tabsetPanel(id = "inTabset", - tabPanel("Data Upload", - sidebarLayout( - sidebarPanel( - h3("Enter the details of the experimental design"), - helpText("First, define the number of comparison groups. - Then, upload your fastq files and assign each fastq file to its group. - Specify any biological or technical replicates, if they exist, - and indicate whether the files are paired-end or single-end. - Review and submit them for the counting step."), - hr(), - h4("Set group numbers"), - helpText("Enter number of groups in your experiment."), - numericInput("num", label = "", value = 0, min = 0), - actionButton("nextnum", "Next"), - conditionalPanel(condition = "input.nextnum > 0", - hr(), - h4("Assign group names"), - helpText("Enter names for each group."), - uiOutput("groupnames"), - actionButton("nextupload", "Next"), - hr() - ), - conditionalPanel(condition = "input.nextupload > 0", - p("Groups are ", textOutput("groups", inline = TRUE)), - hr(), - h4("Upload guide RNA library"), - helpText("Please upload the guide library."), - hr(), - fileInput("uploadguides", label = "", accept = c('.tsv', '.csv', '.txt'), multiple = TRUE), - actionButton("viewguides", "View guide library"), - hr(), - hr(), - h4("Upload sample information"), - helpText("Please upload the file containing sample information."), - hr(), - fileInput("uploadsamples", label = "", accept = c('.tsv', '.csv', '.txt'), multiple = TRUE), - actionButton("viewsamples", "View sample information"), - hr(), - radioButtons("count_matrix_yes_no", label = "Do you have a count matrix?", choices = list("Yes" = "yes", "No" = "no"), selected = ""), - conditionalPanel(condition = "input.count_matrix_yes_no == 'yes'", - h4("Upload count matrix"), - helpText("Please upload the count matrix."), - hr(), - fileInput("uploadcounts", label = "", accept = c('.tsv', '.csv', '.txt'), multiple = TRUE), - actionButton("viewcounts", "View count matrix") - ), - conditionalPanel(condition = "input.count_matrix_yes_no == 'no'", - h4("Upload fastq files"), - fileInput("upload", label = "", accept = c('.fastq', 'fastq.gz'), multiple = TRUE) - ) - ) - ), - mainPanel( - conditionalPanel(condition = "input.viewguides > 0", - hr(), - h4("Guide library"), - DT::dataTableOutput("dataTableGuides") - ), - conditionalPanel(condition = "input.viewsamples > 0", - hr(), - h4("Sample information"), - DT::dataTableOutput("dataTableSamples") - ), - conditionalPanel(condition = "input.count_matrix_yes_no == 'no'", - hr(), - h4("Here are the uploaded Fastq files"), - verbatimTextOutput("fastqFilesOutput"), - actionButton("gotocountingfastq", "Go to Counting") # Button to go to counting - ), - conditionalPanel(condition = "input.count_matrix_yes_no == 'yes' && input.viewcounts > 0", - hr(), - h4("Count matrix"), - DT::dataTableOutput("dataTableCounts"), - actionButton("gotopreprocessing", "Go to preprocessing") - ) - ) - ) - ), - tabPanel("Counting", - sidebarLayout( - sidebarPanel( - h4("Select method of counting"), - selectInput("method", "", choices = c("Rsubread", "MAGeCK", "WEHI")), - actionButton("guidecounts", "Get the guide counts") - ), - mainPanel( - conditionalPanel(condition = "input.guidecounts > 0", - uiOutput("dynamic_ui") - ) - ) - ) - ), - tabPanel("Preprocessing", - sidebarLayout( - sidebarPanel( - h3("Select preprocessing options"), - h4("Select software for analysing your screen"), - selectInput("software", - "", - choices = c("", "MAGeCK", "edgeR"), - selected = NULL), - conditionalPanel( - condition = "input.software == 'edgeR'", - h3("Create edgeR data object"), - actionButton("create_dgelist", "Create DGEList"), - h3("Check the quality of the experiment"), - selectInput("quality_check", - "", - choices = c("", - "View guides distribution", - "View guides cumulative distribution", - "View distribution of genes across samples", - "View heatmap of guide counts"), - selected = NULL) - ), - ), - mainPanel( - textOutput("dgelist_status"), # Display status for DGEList creation - conditionalPanel( - condition = "input.quality_check == 'View guides distribution'", # Display guide distribution - h3("The distribution of SgRNA numbers per gene"), - plotOutput("guide_distribution"), - uiOutput("download_guide_pdf_button") - ), - ) - ) - ), - tabPanel("Differential Analysis", h4("Testing counting"), fluidPage(sidebarPanel())), - tabPanel("Pathway Analysis", h4("Testing counting"), fluidPage(sidebarPanel())) - ) +ui <- navbarPage( + "CuReSPR", id = "main", theme = shinytheme("cerulean"), + tabsetPanel( + id = "inTabset", + tabPanel( + "Data Upload", + sidebarLayout( + sidebarPanel( + h3("Enter the details of the experimental design"), + helpText( + "First, define the number of comparison groups. Then, upload ", + "your fastq files and assign each fastq file to its group. ", + "Specify any biological or technical replicates, if they exist, ", + "and indicate whether the files are paired-end or single-end. ", + "Review and submit them for the counting step." + ), + hr(), + h4("Set group numbers"), + helpText("Enter number of groups in your experiment."), + numericInput("num", label = "", value = 0, min = 0), + actionButton("nextnum", "Next"), + conditionalPanel( + condition = "input.nextnum > 0", + hr(), + h4("Assign group names"), + helpText("Enter names for each group."), + uiOutput("groupnames"), + actionButton("nextupload", "Next"), + hr() + ), + conditionalPanel( + condition = "input.nextupload > 0", + p("Groups are ", textOutput("groups", inline = TRUE)), + hr(), + h4("Upload guide RNA library"), + helpText("Please upload the guide library."), + hr(), + fileInput( + "uploadguides", label = "", + accept = c(".tsv", ".csv", ".txt"), multiple = TRUE + ), + actionButton("viewguides", "View guide library"), + hr(), + hr(), + h4("Upload sample information"), + helpText( + "Please upload the file containing sample information." + ), + hr(), + fileInput( + "uploadsamples", label = "", + accept = c(".tsv", ".csv", ".txt"), multiple = TRUE + ), + actionButton("viewsamples", "View sample information"), + hr(), + radioButtons( + "count_matrix_yes_no", + label = "Do you have a count matrix?", + choices = list("Yes" = "yes", "No" = "no"), selected = "" + ), + conditionalPanel( + condition = "input.count_matrix_yes_no == 'yes'", + h4("Upload count matrix"), + helpText("Please upload the count matrix."), + hr(), + fileInput( + "uploadcounts", label = "", + accept = c(".tsv", ".csv", ".txt"), multiple = TRUE + ), + actionButton("viewcounts", "View count matrix") + ), + conditionalPanel( + condition = "input.count_matrix_yes_no == 'no'", + h4("Upload fastq files"), + fileInput( + "upload", label = "", + accept = c(".fastq", "fastq.gz"), multiple = TRUE + ) + ) + ) + ), + mainPanel( + conditionalPanel( + condition = "input.viewguides > 0", + hr(), + h4("Guide library"), + DT::dataTableOutput("dataTableGuides") + ), + conditionalPanel( + condition = "input.viewsamples > 0", + hr(), + h4("Sample information"), + DT::dataTableOutput("dataTableSamples") + ), + conditionalPanel( + condition = "input.count_matrix_yes_no == 'no'", + hr(), + h4("Here are the uploaded Fastq files"), + verbatimTextOutput("fastqFilesOutput"), + actionButton("gotocountingfastq", "Go to Counting") + ), + conditionalPanel( + condition = "input.count_matrix_yes_no == 'yes' && input.viewcounts > 0", + hr(), + h4("Count matrix"), + DT::dataTableOutput("dataTableCounts"), + actionButton("gotopreprocessing", "Go to preprocessing") + ) + ) + ) + ), + tabPanel( + "Counting", + sidebarLayout( + sidebarPanel( + h4("Select method of counting"), + selectInput( + "method", "", + choices = c("Rsubread", "MAGeCK", "WEHI") + ), + actionButton("guidecounts", "Get the guide counts") + ), + mainPanel( + conditionalPanel( + condition = "input.guidecounts > 0", + uiOutput("dynamic_ui") + ) + ) + ) + ), + tabPanel( + "Preprocessing", + sidebarLayout( + sidebarPanel( + h3("Select preprocessing options"), + h4("Select software for analysing your screen"), + selectInput( + "software", "", + choices = c("", "MAGeCK", "edgeR"), selected = NULL + ), + conditionalPanel( + condition = "input.software == 'edgeR'", + h3("Create edgeR data object"), + actionButton("create_dgelist", "Create DGEList"), + h3("Check the quality of the experiment"), + selectInput( + "quality_check", "", + choices = c( + "", "View guides distribution", + "View guides cumulative distribution", + "View distribution of genes across samples", + "View heatmap of guide counts" + ), + selected = NULL + ) + ) + ), + mainPanel( + textOutput("dgelist_status"), + conditionalPanel( + condition = "input.quality_check == 'View guides distribution'", + h3("The distribution of SgRNA numbers per gene"), + plotOutput("guide_distribution"), + uiOutput("download_guide_pdf_button") + ) + ) + ) + ), + tabPanel("Differential Analysis", + h4("Testing counting"), + fluidPage(sidebarPanel())), + tabPanel("Pathway Analysis", + h4("Testing counting"), + fluidPage(sidebarPanel())) + ) ) # Define server logic @@ -148,7 +191,8 @@ server <- function(input, output, session) { req(input$upload) fastq_file_names <- input$upload$name fastq_uploaded(TRUE) # Mark Fastq files as uploaded - paste("Uploaded Fastq files:", paste(fastq_file_names, collapse = ", ")) + paste("Uploaded Fastq files:", + paste(fastq_file_names, collapse = ", ")) }) # Render DataTables for uploaded files @@ -184,12 +228,13 @@ server <- function(input, output, session) { output$groups <- renderText({ req(input$num) - group_values <- sapply(1:input$num, function(i) input[[paste0("group", i)]]) + group_values <- sapply(1:input$num, + function(i) input[[paste0("group", i)]]) paste("Groups are:", paste(group_values, collapse = ", ")) }) observeEvent(input$gotocountingfastq, { - updateTabsetPanel(session, "inTabset", selected = "Counting") # Navigate to Counting tab after Fastq files loaded + updateTabsetPanel(session, "inTabset", selected = "Counting") }) observeEvent(input$gotopreprocessing, { @@ -201,10 +246,10 @@ server <- function(input, output, session) { output$status <- renderText("Calculating guide counts...") req(input$uploadguides) - # This is just a placeholder. Add logic for the counting process with Rsubread, MAGeCK, etc. later. + # Placeholder for actual logic; add counting logic later count_data <- data.frame( sgRNA_ID = c("sgRNA1", "sgRNA2"), - Count = c(100, 200) # Sample count data; replace with actual counting logic + Count = c(100, 200) # Sample count data ) output$count_table <- renderDT({ @@ -229,71 +274,70 @@ server <- function(input, output, session) { paste0("guide-counts-", Sys.Date(), ".csv") }, content = function(file) { - # Ensure there is data to write req(input$guidecounts) count_data <- data.frame( sgRNA_ID = c("sgRNA1", "sgRNA2"), - Count = c(100, 200) # Sample count data; replace with actual counting logic + Count = c(100, 200) # Sample count data ) write.csv(count_data, file, row.names = FALSE) } ) # DGEList creation - # Declare reactive value for DGEList edgeR_object <- reactiveVal(NULL) observeEvent(input$create_dgelist, { - req(input$uploadcounts, input$uploadsamples) # Ensure necessary files are uploaded + req(input$uploadcounts, input$uploadsamples) # Create the DGEList object - dge <- DGEList(counts = read_file_and_render(input$uploadcounts)[,-c(1:2)], - genes = read_file_and_render(input$uploadguides), - samples = read_file_and_render(input$uploadsamples)) + dge <- DGEList( + counts = read_file_and_render(input$uploadcounts)[,-c(1:2)], + genes = read_file_and_render(input$uploadguides), + samples = read_file_and_render(input$uploadsamples) + ) dge$samples$group <- dge$samples$Groups dge$samples$Groups <- NULL - rownames(dge) <- read_file_and_render(input$uploadcounts)[,1] - # Update the reactive value + rownames(dge) <- read_file_and_render(input$uploadcounts)[, 1] edgeR_object(dge) # Set the edgeR DGEList object output$dgelist_status <- renderText("DGEList created successfully!") - # Print the DGEList output in the Preprocessing tab + output$dge_list_output <- renderPrint({ req(edgeR_object()) - edgeR_object() # Display the DGEList object + edgeR_object() }) - }) # Display quality check outputs - guide_pdf <- function(){ + guide_pdf <- function() { req(edgeR_object()) - barplot(table(table(edgeR_object()$genes$Gene_ID)), xlab = "Number of sgRNA per gene", main = "The distribution of sgRNA per gene", - col = "#CD534CFF", xlim = c(0, 6.4), ylab = "frequency", - border = NA) + barplot( + table(table(edgeR_object()$genes$Gene_ID)), + xlab = "Number of sgRNA per gene", + main = "The distribution of sgRNA per gene", + col = "#CD534CFF", xlim = c(0, 6.4), ylab = "frequency", + border = NA + ) } output$guide_distribution <- renderPlot({ - if(!is.null(guide_pdf())) guide_pdf() + if (!is.null(guide_pdf())) guide_pdf() }) - output$download_guide_pdf <- downloadHandler( + output$download_guide_pdf <- downloadHandler( filename = function() { - paste('guide-distribution', Sys.Date(), '.pdf', sep='') + paste("guide-distribution", Sys.Date(), ".pdf", sep = "") }, content = function(file) { pdf(file) - (guide_pdf()) + guide_pdf() dev.off() } ) - output$download_guide_pdf_button <- renderUI({ - req(guide_pdf()) - downloadButton("download_guide_pdf") - }) - - - + output$download_guide_pdf_button <- renderUI({ + req(guide_pdf()) + downloadButton("download_guide_pdf") + }) } # Run the app