implemented specification of categorical variables (logicals are converted to factor)

This commit is contained in:
Andreas Gammelgaard Damsbo 2024-11-19 12:55:09 +01:00
parent fe9918dc10
commit f5965a2748
No known key found for this signature in database
4 changed files with 113 additions and 12 deletions

View File

@ -62,10 +62,12 @@ read_input <- function(file, consider.na = c("NA", '""', "")) {
} else if (ext == "dta") { } else if (ext == "dta") {
df <- haven::read_dta(file = file) df <- haven::read_dta(file = file)
} else if (ext == "ods") { } else if (ext == "ods") {
df <- readODS::read_ods(file = file) df <- readODS::read_ods(path = file)
} else { } else if (ext == "rds") {
df <- readr::read_rds(file = file)
}else {
stop("Input file format has to be on of: stop("Input file format has to be on of:
'.csv', '.xls', '.xlsx', '.dta' or '.ods'") '.csv', '.xls', '.xlsx', '.dta', '.rds' or '.ods'")
} }
}, },
error = function(e) { error = function(e) {

View File

@ -0,0 +1,10 @@
name: redcapcast
title:
username: agdamsbo
account: agdamsbo
server: shinyapps.io
hostUrl: https://api.shinyapps.io/v1
appId: 11351429
bundleId:
url: https://agdamsbo.shinyapps.io/redcapcast/
version: 1

View File

@ -7,7 +7,7 @@ library(readr)
library(dplyr) library(dplyr)
library(here) library(here)
library(devtools) library(devtools)
if (!requireNamespace("REDCapCAST")){ if (!requireNamespace("REDCapCAST")) {
devtools::install_github("agdamsbo/REDCapCAST", quiet = TRUE, upgrade = "never") devtools::install_github("agdamsbo/REDCapCAST", quiet = TRUE, upgrade = "never")
} }
library(REDCapCAST) library(REDCapCAST)
@ -21,8 +21,35 @@ server <- function(input, output, session) {
dat <- shiny::reactive({ dat <- shiny::reactive({
shiny::req(input$ds) shiny::req(input$ds)
read_input(input$ds$datapath) |> out <- read_input(input$ds$datapath)
parse_data()
# Saves labels to reapply later
labels <- lapply(out, get_attr)
out <- out |>
## Parses data with readr functions
parse_data() |>
## Converts logical to factor, which overwrites attributes
##
dplyr::mutate(dplyr::across(dplyr::where(is.logical), forcats::as_factor))
if (!is.null(input$factor_vars)) {
out <- out |>
dplyr::mutate(
dplyr::across(
dplyr::all_of(input$factor_vars),
forcats::as_factor
)
)
}
# Old attributes are appended
out <- purrr::imap(out,\(.x,.i){
set_attr(.x,labels[[.i]])
}) |>
dplyr::bind_cols()
out
}) })
# getData <- reactive({ # getData <- reactive({
@ -48,19 +75,66 @@ server <- function(input, output, session) {
shiny::outputOptions(output, "uploaded", suspendWhenHidden = FALSE) shiny::outputOptions(output, "uploaded", suspendWhenHidden = FALSE)
output$factor_vars <- shiny::renderUI({
shiny::req(input$ds)
selectizeInput(
inputId = "factor_vars",
selected = colnames(dat())[sapply(dat(), is.factor)],
label = "Covariables to format as categorical",
choices = colnames(dat()),
multiple = TRUE
)
})
output$data.tbl <- gt::render_gt( output$data.tbl <- gt::render_gt(
dd() |> dd() |>
purrr::pluck("data") |> purrr::pluck("data") |>
head(20) |> head(20) |>
dplyr::tibble() |> # dplyr::tibble() |>
gt::gt() gt::gt() |>
gt::tab_style(
style = gt::cell_text(weight = "bold"),
locations = gt::cells_column_labels(dplyr::everything())
) |>
gt::tab_header(
title = "Imported data preview",
subtitle = "The first 20 subjects of the supplied dataset for reference."
)
) )
output$meta.tbl <- gt::render_gt( output$meta.tbl <- gt::render_gt(
dd() |> dd() |>
purrr::pluck("meta") |> purrr::pluck("meta") |>
dplyr::tibble() |> # dplyr::tibble() |>
gt::gt() dplyr::mutate(
dplyr::across(
dplyr::everything(),
\(.x) {
.x[is.na(.x)] <- ""
return(.x)
}
)
) |>
dplyr::select(1:8) |>
gt::gt() |>
gt::tab_style(
style = gt::cell_text(weight = "bold"),
locations = gt::cells_column_labels(dplyr::everything())
) |>
gt::tab_header(
title = "Generated metadata",
subtitle = "Only the first 8 columns are modified using REDCapCAST. Download the metadata to see everything."
) |>
gt::tab_style(
style = gt::cell_borders(
sides = c("left", "right"),
color = "grey80",
weight = gt::px(1)
),
locations = gt::cells_body(
columns = dplyr::everything()
)
)
) )
# Downloadable csv of dataset ---- # Downloadable csv of dataset ----
@ -73,7 +147,7 @@ server <- function(input, output, session) {
# Downloadable csv of data dictionary ---- # Downloadable csv of data dictionary ----
output$downloadMeta <- shiny::downloadHandler( output$downloadMeta <- shiny::downloadHandler(
filename = "datadictionary_ready.csv", filename = paste0("REDCapCAST_DataDictionary_", Sys.Date(), ".csv"),
content = function(file) { content = function(file) {
write.csv(purrr::pluck(dd(), "meta"), file, row.names = FALSE, na = "") write.csv(purrr::pluck(dd(), "meta"), file, row.names = FALSE, na = "")
} }

View File

@ -6,7 +6,7 @@ ui <-
title = "Easy REDCap database creation", title = "Easy REDCap database creation",
sidebar = bslib::sidebar( sidebar = bslib::sidebar(
width = 300, width = 300,
shiny::h5("1) Database meta data"), shiny::h5("Metadata casting"),
shiny::fileInput( shiny::fileInput(
inputId = "ds", inputId = "ds",
label = "Upload spreadsheet", label = "Upload spreadsheet",
@ -16,6 +16,7 @@ ui <-
".xls", ".xls",
".xlsx", ".xlsx",
".dta", ".dta",
".rds",
".ods" ".ods"
) )
), ),
@ -29,6 +30,20 @@ ui <-
# This has been solved by adding an arbitrary button to load data - which was abandoned again # This has been solved by adding an arbitrary button to load data - which was abandoned again
shiny::conditionalPanel( shiny::conditionalPanel(
condition = "output.uploaded=='yes'", condition = "output.uploaded=='yes'",
shiny::radioButtons(
inputId = "specify_factors",
label = "Specify categorical variables?",
selected = "no",
inline = TRUE,
choices = list(
"No" = "no",
"Yes" = "yes"
)
),
shiny::conditionalPanel(
condition = "input.specify_factors=='yes'",
uiOutput("factor_vars")
),
# condition = "input.load_data", # condition = "input.load_data",
# shiny::helpText("Below you can download the dataset formatted for upload and the # shiny::helpText("Below you can download the dataset formatted for upload and the
# corresponding data dictionary for a new data base, if you want to upload manually."), # corresponding data dictionary for a new data base, if you want to upload manually."),