mirror of
https://github.com/agdamsbo/REDCapCAST.git
synced 2026-06-19 05:07:30 +02:00
first commit to add shiny app for basic upload of dictionary and dataset
This commit is contained in:
parent
796826d7d9
commit
05c0f35016
12 changed files with 333 additions and 5 deletions
183
R/shiny_cast.R
Normal file
183
R/shiny_cast.R
Normal file
|
|
@ -0,0 +1,183 @@
|
|||
#' Shiny server factory
|
||||
#'
|
||||
#' @return shiny server
|
||||
#' @export
|
||||
server_factory <- function() {
|
||||
function(input, output, session) {
|
||||
require(REDCapCAST)
|
||||
|
||||
dat <- shiny::reactive({
|
||||
shiny::req(input$ds)
|
||||
|
||||
read_input(input$ds$datapath)
|
||||
})
|
||||
|
||||
dd <- shiny::reactive({
|
||||
ds2dd_detailed(data = dat())
|
||||
})
|
||||
|
||||
|
||||
output$data.tbl <- shiny::renderTable({
|
||||
dd() |>
|
||||
purrr::pluck("data") |>
|
||||
head(20) |>
|
||||
dplyr::tibble()
|
||||
})
|
||||
|
||||
output$meta.tbl <- shiny::renderTable({
|
||||
dd() |>
|
||||
purrr::pluck("meta") |>
|
||||
dplyr::tibble()
|
||||
})
|
||||
|
||||
# Downloadable csv of dataset ----
|
||||
output$downloadData <- shiny::downloadHandler(
|
||||
filename = "data_ready.csv",
|
||||
content = function(file) {
|
||||
write.csv(purrr::pluck(dd(), "data"), file, row.names = FALSE)
|
||||
}
|
||||
)
|
||||
|
||||
# Downloadable csv of data dictionary ----
|
||||
output$downloadMeta <- shiny::downloadHandler(
|
||||
filename = "dictionary_ready.csv",
|
||||
content = function(file) {
|
||||
write.csv(purrr::pluck(dd(), "meta"), file, row.names = FALSE)
|
||||
}
|
||||
)
|
||||
output$upload.data.print <- shiny::renderPrint({
|
||||
shiny::eventReactive(input$upload.meta, {
|
||||
shiny::req(input$uri)
|
||||
|
||||
shiny::req(input$api)
|
||||
|
||||
REDCapR::redcap_metadata_write(
|
||||
ds = purrr::pluck(dd(), "meta"),
|
||||
redcap_uri = input$uri,
|
||||
token = input$api
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
output$upload.data.print <- shiny::renderPrint({
|
||||
shiny::eventReactive(input$upload.data, {
|
||||
shiny::req(input$uri)
|
||||
|
||||
shiny::req(input$api)
|
||||
|
||||
REDCapR::redcap_write(
|
||||
ds = purrr::pluck(dd(), "data"),
|
||||
redcap_uri = input$uri,
|
||||
token = input$api
|
||||
)
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#' UI factory for shiny app
|
||||
#'
|
||||
#' @return shiny ui
|
||||
#' @export
|
||||
ui_factory <- function() {
|
||||
# require(ggplot2)
|
||||
|
||||
shiny::fluidPage(
|
||||
|
||||
## -----------------------------------------------------------------------------
|
||||
## Application title
|
||||
## -----------------------------------------------------------------------------
|
||||
shiny::titlePanel("Simple REDCap data base creation and data upload from data set file via API",
|
||||
windowTitle = "REDCap databse creator"
|
||||
),
|
||||
shiny::h5("Please note, that this tool serves as a demonstration of some of the functionality
|
||||
of the REDCapCAST package. No responsibility for data loss or any other
|
||||
problems will be taken."),
|
||||
|
||||
## -----------------------------------------------------------------------------
|
||||
## Side panel
|
||||
## -----------------------------------------------------------------------------
|
||||
|
||||
shiny::sidebarPanel(
|
||||
shiny::h4("REDCap database and dataset"),
|
||||
shiny::fileInput("ds", "Choose data file",
|
||||
multiple = FALSE,
|
||||
accept = c(
|
||||
".csv",
|
||||
".xls",
|
||||
".xlsx",
|
||||
".dta"
|
||||
)
|
||||
),
|
||||
shiny::h6("Below you can download the dataset formatted for upload and the
|
||||
corresponding data dictionary for a new data base."),
|
||||
# Button
|
||||
shiny::downloadButton("downloadData", "Download data"),
|
||||
|
||||
# Button
|
||||
shiny::downloadButton("downloadMeta", "Download dictionary"),
|
||||
|
||||
|
||||
# Horizontal line ----
|
||||
shiny::tags$hr(),
|
||||
shiny::h4("REDCap upload"),
|
||||
shiny::textInput(
|
||||
inputId = "uri",
|
||||
label = "URI",
|
||||
value = ""
|
||||
),
|
||||
shiny::textInput(
|
||||
inputId = "api",
|
||||
label = "API key",
|
||||
value = ""
|
||||
),
|
||||
shiny::actionButton(
|
||||
inputId = "upload.meta",
|
||||
label = "Upload dictionary", icon = icon("book-bookmark")
|
||||
),
|
||||
shiny::h6("Please note, that before uploading any real data, put your project
|
||||
into production mode."),
|
||||
shiny::actionButton(
|
||||
inputId = "upload.datata",
|
||||
label = "Upload data", icon = icon("upload")
|
||||
),
|
||||
|
||||
# Horizontal line ----
|
||||
shiny::tags$hr()
|
||||
),
|
||||
shiny::mainPanel(
|
||||
shiny::tabsetPanel(
|
||||
|
||||
## -----------------------------------------------------------------------------
|
||||
## Summary tab
|
||||
## -----------------------------------------------------------------------------
|
||||
shiny::tabPanel(
|
||||
"Summary",
|
||||
shiny::h3("Data overview (first 20)"),
|
||||
shiny::htmlOutput("data.tbl", container = span),
|
||||
shiny::h3("Dictionary overview"),
|
||||
shiny::htmlOutput("meta.tbl", container = span)
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
#' Launch the included Shiny-app for database casting and upload
|
||||
#'
|
||||
#' @return shiny app
|
||||
#' @export
|
||||
#'
|
||||
#' @examples
|
||||
#' # shiny_cast()
|
||||
#'
|
||||
shiny_cast <- function() {
|
||||
# shiny::runApp(appDir = here::here("app/"), launch.browser = TRUE)
|
||||
|
||||
shiny::shinyApp(
|
||||
ui_factory(),
|
||||
server_factory()
|
||||
)
|
||||
}
|
||||
50
R/utils.r
50
R/utils.r
|
|
@ -490,3 +490,53 @@ is_repeated_longitudinal <- function(data, generics = c(
|
|||
}
|
||||
any(generics %in% names)
|
||||
}
|
||||
|
||||
|
||||
|
||||
#' Helper to import files correctly
|
||||
#'
|
||||
#' @param filenames file names
|
||||
#'
|
||||
#' @return character vector
|
||||
#' @export
|
||||
#'
|
||||
#' @examples
|
||||
#' file_extension(list.files(here::here(""))[[2]])[[1]]
|
||||
file_extension <- function(filenames) {
|
||||
sub(pattern = "^(.*\\.|[^.]+)(?=[^.]*)", replacement = "", filenames, perl = TRUE)
|
||||
}
|
||||
|
||||
#' Flexible file import based on extension
|
||||
#'
|
||||
#' @param file file name
|
||||
#' @param consider.na character vector of strings to consider as NAs
|
||||
#'
|
||||
#' @return tibble
|
||||
#' @export
|
||||
#'
|
||||
#' @examples
|
||||
#' read_input("https://raw.githubusercontent.com/agdamsbo/cognitive.index.lookup/main/data/sample.csv")
|
||||
read_input <- function(file, consider.na= c("NA", '""',"")){
|
||||
|
||||
ext <- file_extension(file)
|
||||
|
||||
tryCatch(
|
||||
{
|
||||
if (ext == "csv") {
|
||||
df <- readr::read_csv(file = file,na = consider.na)
|
||||
} else if (ext %in% c("xls", "xlsx")) {
|
||||
df <- openxlsx2::read_xlsx(file = file, na.strings = consider.na)
|
||||
} else if (ext == "dta"){
|
||||
df <- haven::read_dta(file = file)
|
||||
} else {
|
||||
stop("Input file format has to be either '.csv', '.xls' or '.xlsx'")
|
||||
}
|
||||
},
|
||||
error = function(e) {
|
||||
# return a safeError if a parsing error occurs
|
||||
stop(shiny::safeError(e))
|
||||
}
|
||||
)
|
||||
|
||||
df
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue