diff --git a/DESCRIPTION b/DESCRIPTION index e7a8e6b..0748e3f 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -9,7 +9,7 @@ Description: The metRscreen shiny app allows you to screen papers via their abst License: MIT + file LICENSE Encoding: UTF-8 Roxygen: list(markdown = TRUE) -RoxygenNote: 7.3.1 +RoxygenNote: 7.3.2 Imports: bslib, dplyr, diff --git a/R/runApp.R b/R/runApp.R index 78e0ce5..d065d73 100644 --- a/R/runApp.R +++ b/R/runApp.R @@ -2,14 +2,14 @@ #' @description The metRscreen shiny app allows you to screen papers via their abstracts and titles and allows for highlighting of keywords in multiple colours. #' @return A dataframe of decisioned papers #' @param screen.file path to the csv file containing references you wish to screen. -#' @param reject.vec vector of rejection reasons to be added to metRscreen, can be left empty +#' @param reject.list list of rejection reasons to be added to metRscreen, can be left empty #' @param collab.names vector of names to identify screeners to be added to metRscreen, can be left empty #' @export -metRscreen <- function(screen.file, reject.vec = NULL, collab.names = NULL) { +metRscreen <- function(screen.file, reject.list = NULL, collab.names = NULL) { # if data.str if missing, assign an empty data.frame if (missing(screen.file)) cat("\nError: Please provide a .csv file to screen\n") - if (missing(reject.vec)) reject.vec <- NULL + if (missing(reject.list)) reject.list <- NULL if (missing(collab.names)) collab.names <- NULL if (file.exists(screen.file)) { @@ -25,7 +25,7 @@ metRscreen <- function(screen.file, reject.vec = NULL, collab.names = NULL) { shiny_env <- 1 envir <- as.environment(shiny_env) assign("screen.file", screen.file, envir = envir) - assign("reject.vec", reject.vec, envir = envir) + assign("reject.list", reject.list, envir = envir) assign("collab.names", collab.names, envir = envir) assign("screen.history", screen.history, envir = envir) diff --git a/README.md b/README.md index 81e76aa..39c060c 100644 --- a/README.md +++ b/README.md @@ -34,10 +34,10 @@ metRscreen(screen.file = "~/Desktop/Example.csv") ``` ## metRscreen arguments -You can give specific rejection reasons as a vector with "reject.vec = c()". +You can give specific rejection reasons as a vector with "reject.list = c()". ```{r} -metRscreen(screen.file = "~/Desktop/Example.csv", reject.vec = c("no control", "wrong study system")) +metRscreen(screen.file = "~/Desktop/Example.csv", reject.list = c("no control", "wrong study system")) ``` The .rds file that's produced allows for reloading of previous screening decisions. This will be automatically reloaded the next instance metRscreen is run and will return screening to the same state (i.e. with the same reject list, hidden or showing paper components, and any previous screening decisions). diff --git a/inst/metRscreen/server.R b/inst/metRscreen/server.R index 868fcf9..59d0d2a 100644 --- a/inst/metRscreen/server.R +++ b/inst/metRscreen/server.R @@ -4,7 +4,7 @@ server <- function(input, output, session) { # settings object settings.store <- shiny::reactiveValues( - reject.vec = NULL, + reject.list = NULL, counter = NULL, datapath = NULL, new.data = NULL, @@ -29,6 +29,9 @@ server <- function(input, output, session) { # create a new dataframe based on the old data in a reactive ovject original <- shiny::reactiveValues(new.data = NULL) + + # create a new dataframe for hcecking + check_dat <- shiny::reactiveValues(check = NULL) # create a temp data file temp <- shiny::reactiveValues(import.data = NULL) @@ -77,6 +80,7 @@ server <- function(input, output, session) { # input dataframe and create saving empty template####### shiny::observe({ + if (is.null(screen.history) & import$first.load == TRUE) { original$new.data <- cbind( read.csv(screen.file), @@ -85,17 +89,51 @@ server <- function(input, output, session) { Comment = "No comments given", Screen.Name = "No screener name given" ) + import$first.load <- FALSE + countertot$total <- nrow(original$new.data) cat("\nReading in new screening file and creating new screening output(s)\n") + } else if (!is.null(screen.history) & import$first.load == TRUE) { + settings.store <<- do.call("reactiveValues", readRDS(screen.history)) - original$new.data <- settings.store$new.data - cat("\nReading in saved screening file and using existing screening output\n") - import$first.load <- FALSE - import$first.import <- TRUE + check_dat$check <- read.csv(screen.file) + countertot$total <- nrow(settings.store$new.data) counter$countervalue <- settings.store$counter + + + if (isTRUE(all.equal(settings.store$new.data$Title, check_dat$check$Title))) { + + original$new.data <- settings.store$new.data + + import$first.load <- FALSE + import$first.import <- TRUE + cat("\nReading in saved screening file and using existing screening output\n") + + + } else if(!isTRUE(all.equal(settings.store$new.data$Title, check_dat$check$Title))) { + + cat("\nData frame inconsistencies between saved and loaded data frames - please revert to previous version\n") + shinyalert::shinyalert( + title = "Warning", + text = "Data frame inconsistencies between saved and loaded data frames - please revert to previous version", + size = "m", + closeOnClickOutside = FALSE, + html = TRUE, + type = "warning", + showConfirmButton = TRUE, + showCancelButton = FALSE, + confirmButtonText = "OK", + confirmButtonCol = "#AEDEF4", + animation = TRUE, + imageHeight = "88", + imageWidth = "80" + ) + shiny::stopApp() + } } + # save a temp output settings.store$counter <- counter$countervalue settings.store$new.data <- original$new.data @@ -114,10 +152,10 @@ server <- function(input, output, session) { shiny::observe({ if (!is.null(screen.history) & import$first.import == "TRUE") { # update params - if (!identical(reject.vec, settings.store$reject.vec) & !is.null(reject.vec)) { - reject.vec <<- reject.vec + if (!identical(reject.list, settings.store$reject.list) & !is.null(reject.list)) { + reject.list <<- reject.list } else { - reject.vec <<- settings.store$reject.vec + reject.list <<- settings.store$reject.list } if (!identical(collab.names, settings.store$collab.names) & !is.null(collab.names)) { @@ -196,12 +234,12 @@ server <- function(input, output, session) { # update radiogroup with imported reasons#### shiny::observe({ - if (length(reject.vec > 0)) { + if (length(reject.list > 0)) { shinyjs::show("reject.reason") shinyWidgets::updatePrettyRadioButtons( session = session, inputId = "reject.reason", - choices = reject.vec, + choices = reject.list, selected = character(0), inline = TRUE, prettyOptions = list( @@ -212,19 +250,10 @@ server <- function(input, output, session) { ) ) - settings.store$reject.vec <- reject.vec + settings.store$reject.list <- reject.list } }) - - - - - # counter total###### - shiny::observe({ - countertot$total <- nrow(original$new.data) - }) - # change the study with next and previous####### shiny::observeEvent(input$Next, { counter$countervalue <- counter$countervalue + 1 @@ -265,27 +294,27 @@ server <- function(input, output, session) { ) )) }) - + # render title text highlighted based on search###### output$title <- shiny::renderUI({ shiny::HTML(paste( "", highlight_text(as.character(StudyData()$Title), - search = list( - input$search1, - input$search2, - input$search3, - input$search4, - input$search5 - ) + search = list( + input$search1, + input$search2, + input$search3, + input$search4, + input$search5 + ) ), "" )) }) - #error + # error output$hist.reason <- shiny::renderUI({ - if(StudyData()$Screen == "Reject"){ + if (StudyData()$Screen == "Reject") { shiny::HTML(paste( "

", "Reject Reason:", @@ -305,21 +334,21 @@ server <- function(input, output, session) { }) output$screen.comment <- shiny::renderUI({ - shiny::HTML(paste( - "

", - "Comment:", - as.character(StudyData()$Comment), - "

" - )) + shiny::HTML(paste( + "

", + "Comment:", + as.character(StudyData()$Comment), + "

" + )) }) output$name.screener <- shiny::renderUI({ - shiny::HTML(paste( - "

", - "Screener:", - as.character(StudyData()$Screen.Name), - "

" - )) + shiny::HTML(paste( + "

", + "Screener:", + as.character(StudyData()$Screen.Name), + "

" + )) }) output$author <- shiny::renderUI({ @@ -371,7 +400,7 @@ server <- function(input, output, session) { shinyalert::shinyalert( title = "Congratulations", text = "You've finished screening all papers!", - size = "s", + size = "s", closeOnEsc = TRUE, closeOnClickOutside = TRUE, html = FALSE, @@ -384,7 +413,7 @@ server <- function(input, output, session) { imageUrl = "", animation = TRUE ) - cat(paste("\nCongratulations - you have finished screening", countertot$total, "papers \n")) + cat(paste("\nCongratulations - you have finished screening", countertot$total, "papers \n")) counter$countervalue <- countertot$total } if (counter$countervalue == 0) { @@ -401,7 +430,7 @@ server <- function(input, output, session) { shinyWidgets::updatePrettyRadioButtons( session = session, inputId = "reject.reason", - choices = reject.vec, + choices = reject.list, selected = character(0), inline = TRUE, prettyOptions = list( @@ -433,7 +462,7 @@ server <- function(input, output, session) { shiny::observeEvent(input$Reject, { original$new.data[counter$countervalue, ]$Screen <- "Reject" - if (length(input$reject.reason > 0)) { + if (length(input$reject.reason > 0) & input$reject.reason != "") { original$new.data[counter$countervalue, ]$Reason <- input$reject.reason } if (input$comments != "") { @@ -453,7 +482,7 @@ server <- function(input, output, session) { shinyalert::shinyalert( title = "Congratulations", text = "You've finished screening all papers!", - size = "s", + size = "s", closeOnEsc = TRUE, closeOnClickOutside = TRUE, html = FALSE, @@ -466,7 +495,7 @@ server <- function(input, output, session) { imageUrl = "", animation = TRUE ) - cat(paste("\nCongratulations - you have finished screening", countertot$total, "papers \n")) + cat(paste("\nCongratulations - you have finished screening", countertot$total, "papers \n")) counter$countervalue <- countertot$total } if (counter$countervalue == 0) { @@ -478,7 +507,7 @@ server <- function(input, output, session) { shinyWidgets::updatePrettyRadioButtons( session = session, inputId = "reject.reason", - choices = reject.vec, + choices = reject.list, selected = character(0), inline = TRUE, prettyOptions = list( @@ -530,7 +559,7 @@ server <- function(input, output, session) { shinyalert::shinyalert( title = "Congratulations", text = "You've finished screening all papers!", - size = "s", + size = "s", closeOnEsc = TRUE, closeOnClickOutside = TRUE, html = FALSE, @@ -543,7 +572,7 @@ server <- function(input, output, session) { imageUrl = "", animation = TRUE ) - cat(paste("\nCongratulations - you have finished screening", countertot$total, "papers \n")) + cat(paste("\nCongratulations - you have finished screening", countertot$total, "papers \n")) counter$countervalue <- countertot$total } if (counter$countervalue == 0) { @@ -555,7 +584,7 @@ server <- function(input, output, session) { shinyWidgets::updatePrettyRadioButtons( session = session, inputId = "reject.reason", - choices = reject.vec, + choices = reject.list, selected = character(0), inline = TRUE, prettyOptions = list( diff --git a/man/metRscreen.Rd b/man/metRscreen.Rd index 1c8d267..373176b 100644 --- a/man/metRscreen.Rd +++ b/man/metRscreen.Rd @@ -4,12 +4,12 @@ \alias{metRscreen} \title{Run the metRscreen paper screening app} \usage{ -metRscreen(screen.file, reject.vec = NULL, collab.names = NULL) +metRscreen(screen.file, reject.list = NULL, collab.names = NULL) } \arguments{ \item{screen.file}{path to the csv file containing references you wish to screen.} -\item{reject.vec}{vector of rejection reasons to be added to metRscreen, can be left empty} +\item{reject.list}{list of rejection reasons to be added to metRscreen, can be left empty} \item{collab.names}{vector of names to identify screeners to be added to metRscreen, can be left empty} } diff --git a/metRscreen.Rproj b/metRscreen.Rproj index 21a4da0..44e11d0 100644 --- a/metRscreen.Rproj +++ b/metRscreen.Rproj @@ -1,4 +1,5 @@ Version: 1.0 +ProjectId: bce1fe8b-f015-4032-af0d-02ecf1f3463c RestoreWorkspace: Default SaveWorkspace: Default