# DQAgui - A graphical user interface (GUI) to the functions implemented in the R package 'DQAstats'. # Copyright (C) 2019 Universitätsklinikum Erlangen # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. #' @title moduleDescriptiveServer #' #' @param input Shiny server input object #' @param output Shiny server output object #' @param session Shiny session object #' @param rv The global 'reactiveValues()' object, defined in server.R #' @param input_re The Shiny server input object, wrapped into a reactive expression: input_re = reactive({input}) #' #' @export #' # moduleDescriptiveServer moduleDescriptiveServer <- function(input, output, session, rv, input_re){ observe({ req(rv$results_descriptive) # render select input here output$descr_selection_uiout <- renderUI({ selectInput("moduleDescriptive-var_select", "Select variable", rv$variable_list, multiple=FALSE, selectize=FALSE, size = 10) }) # generate output tables observeEvent(input_re()[["moduleDescriptive-var_select"]], { cat(input_re()[["moduleDescriptive-var_select"]], "\n") # get description object desc_out <- rv$results_descriptive[[input_re()[["moduleDescriptive-var_select"]]]]$description count_out <- rv$results_descriptive[[input_re()[["moduleDescriptive-var_select"]]]]$counts stat_out <- rv$results_descriptive[[input_re()[["moduleDescriptive-var_select"]]]]$statistics value_conf <- rv$conformance$value_conformance[[input_re()[["moduleDescriptive-var_select"]]]] output$descr_description <- renderText({ d <- desc_out$source_data$description # https://community.rstudio.com/t/rendering-markdown-text/11588 out <- knitr::knit2html(text = d, fragment.only = TRUE) # output non-escaped HTML string shiny::HTML(out) }) # render source description output$descr_selection_description_source <- renderTable({ o <- desc_out$source_data c <- count_out$source_data data.table::data.table(" " = c("Variable name:", "Source table:", "FHIR ressource:", "DQ-internal Variable Name:", "Variable type:"), " " = c(o$var_name, o$table_name, o$fhir, c$cnt$variable, c$type)) }) # render target description output$descr_selection_description_target <- renderTable({ o <- desc_out$target_data c <- count_out$target_data data.table::data.table(" " = c("Variable name:", "Source table:", "FHIR ressource:", "DQ-internal Variable Name:", "Variable type:"), " " = c(o$var_name, o$table_name, o$fhir, c$cnt$variable, c$type)) }) # render source counts output$descr_selection_counts_source <- renderTable({ tryCatch({ o <- count_out$source_data$cnt[,c("variable", "distinct", "valids", "missings"),with=F] data.table::data.table(" " = c("Distinct values:", "Valid values:", "Missing values:"), " " = c(o$distinct, o$valids, o$missings)) }, error=function(e){shinyjs::logjs(e)}) }) # render target counts output$descr_selection_counts_target <- renderTable({ tryCatch({ o <- count_out$target_data$cnt[,c("variable", "distinct", "valids", "missings"),with=F] data.table::data.table(" " = c("Distinct values:", "Valid values:", "Missing values:"), " " = c(o$distinct, o$valids, o$missings)) }, error=function(e){shinyjs::logjs(e)}) }) # render source statistics output$descr_selection_source_table <- renderTable({ stat_out$source_data }) # render target statistics output$descr_selection_target_table <- renderTable({ stat_out$target_data }) # conformance source # render conformance checks (only if value set present) if (!is.na(desc_out$source_data$checks$value_set)){ # workaround to tell ui, that value_set is there output$gotValueset_s <- reactive({ return(TRUE) }) output$descr_checks_source <- renderUI({ h <- h5(tags$b("Value set:")) v <- verbatimTextOutput("moduleDescriptive-descr_checks_source_valueset") ch <- h5(tags$b("Value conformance:")) ce <- h5(paste0("Conformance check: ", ifelse(value_conf$target_data$conformance_error, "failed", "passed"))) cu <- uiOutput("moduleDescriptive-descr_conformance_source") do.call(tagList, list(h, v, tags$hr(), ch, ce, cu)) }) json_obj_src <- jsonlite::fromJSON(desc_out$source_data$checks$value_set) if (desc_out$source_data$checks$var_type == "factor"){ output$descr_checks_source_valueset <- renderText({ json_obj_src[["value_set"]] }) } else if (desc_out$source_data$checks$var_type %in% c("integer", "numeric")){ output$descr_checks_source_valueset <- renderPrint({ json_obj_src }) } # render automatic conformance checks source # value conformance if (isTRUE(value_conf$source_data$conformance_error)){ output$descr_conformance_source <- renderUI({ v <- verbatimTextOutput("moduleDescriptive-descr_conformance_source_results") do.call(tagList, list(v)) }) output$descr_conformance_source_results <- renderText({ value_conf$source_data$conformance_results }) } else { output$descr_conformance_source <- renderUI({ }) } } else { # workaround to tell ui, that value_set is not there output$gotValueset_s <- reactive({ return(FALSE) }) } outputOptions(output, 'gotValueset_s', suspendWhenHidden=FALSE) # conformance target # render conformance checks (only if value set present) if (!is.na(desc_out$target_data$checks$value_set)){ # workaround to tell ui, that value_set is there output$gotValueset_t <- reactive({ return(TRUE) }) output$descr_checks_target <- renderUI({ h <- h5(tags$b("Value set:")) v <- verbatimTextOutput("moduleDescriptive-descr_checks_target_valueset") ch <- h5(tags$b("Value conformance:")) ce <- h5(paste0("Conformance check: ", ifelse(value_conf$target_data$conformance_error, "failed", "passed"))) cu <- uiOutput("moduleDescriptive-descr_conformance_target") do.call(tagList, list(h, v, tags$hr(), ch, ce, cu)) }) json_obj_tar <- jsonlite::fromJSON(desc_out$target_data$checks$value_set) if (desc_out$target_data$checks$var_type == "factor"){ output$descr_checks_target_valueset <- renderText({ json_obj_tar[["value_set"]] }) } else if (desc_out$target_data$checks$var_type %in% c("integer", "numeric")){ output$descr_checks_target_valueset <- renderPrint({ json_obj_tar }) } # render automatic conformance checks target # value conformance if (isTRUE(value_conf$target_data$conformance_error)){ output$descr_conformance_target <- renderUI({ v <- verbatimTextOutput("moduleDescriptive-descr_conformance_target_results") do.call(tagList, list(v)) }) output$descr_conformance_target_results <- renderText({ value_conf$target_data$conformance_results }) } else { output$descr_conformance_target <- renderUI({ }) } } else { # workaround to tell ui, that value_set is not there output$gotValueset_t <- reactive({ return(FALSE) }) } outputOptions(output, 'gotValueset_t', suspendWhenHidden=FALSE) }) }) } #' @title moduleDescriptiveUI #' #' @param id A character. The identifier of the shiny object #' #' @export #' # moduleDescriptiveUI moduleDescriptiveUI <- function(id){ ns <- NS(id) tagList( fluidRow( box(title = "Select variable", uiOutput(ns("descr_selection_uiout")), width = 4 ), box(title = "Description", htmlOutput(ns("descr_description")), width = 8 )), fluidRow( box(title="Source Data System", width = 6, fluidRow( column(8, h5(tags$b("Metadata")), tableOutput(ns("descr_selection_description_source")) ), column(4, h5(tags$b("Completeness Overview")), tableOutput(ns("descr_selection_counts_source")) ) ), fluidRow( column(8, h5(tags$b("Results")), tableOutput(ns("descr_selection_source_table")) ), column(4, conditionalPanel( condition = "output['moduleDescriptive-gotValueset_s']", uiOutput(ns("descr_checks_source")) ) ) )), box(title="Target Data System", width = 6, fluidRow( column(8, h5(tags$b("Metadata")), tableOutput(ns("descr_selection_description_target")) ), column(4, h5(tags$b("Completeness Overview")), tableOutput(ns("descr_selection_counts_target")) ) ), fluidRow( column(8, h5(tags$b("Results")), tableOutput(ns("descr_selection_target_table")) ), column(4, conditionalPanel( condition = "output['moduleDescriptive-gotValueset_t']", uiOutput(ns("descr_checks_target")) ) ) )) ) ) }