mirror of
https://github.com/agdamsbo/REDCapCAST.git
synced 2026-06-21 05:59:07 +02:00
linting
This commit is contained in:
parent
a0730cb41c
commit
9e33057c06
32 changed files with 456 additions and 340 deletions
|
|
@ -24,19 +24,19 @@
|
|||
#'
|
||||
#' # Get the records
|
||||
#' records <- postForm(
|
||||
#' uri = api_url, # Supply your site-specific URI
|
||||
#' uri = api_url, # Supply your site-specific URI
|
||||
#' token = api_token, # Supply your own API token
|
||||
#' content = 'record',
|
||||
#' format = 'json',
|
||||
#' returnFormat = 'json'
|
||||
#' content = "record",
|
||||
#' format = "json",
|
||||
#' returnFormat = "json"
|
||||
#' )
|
||||
#'
|
||||
#' # Get the metadata
|
||||
#' metadata <- postForm(
|
||||
#' uri = api_url, # Supply your site-specific URI
|
||||
#' uri = api_url, # Supply your site-specific URI
|
||||
#' token = api_token, # Supply your own API token
|
||||
#' content = 'metadata',
|
||||
#' format = 'json'
|
||||
#' content = "metadata",
|
||||
#' format = "json"
|
||||
#' )
|
||||
#'
|
||||
#' # Convert exported JSON strings into a list of data.frames
|
||||
|
|
@ -49,7 +49,8 @@
|
|||
#'
|
||||
#' # Get the metadata
|
||||
#' metadata <- read.csv(
|
||||
#' "/path/to/data/ExampleProject_DataDictionary_2018-06-03.csv")
|
||||
#' "/path/to/data/ExampleProject_DataDictionary_2018-06-03.csv"
|
||||
#' )
|
||||
#'
|
||||
#' # Split the tables
|
||||
#' REDCapRITS::REDCap_split(records, metadata)
|
||||
|
|
@ -86,9 +87,8 @@ REDCap_split <- function(records,
|
|||
metadata,
|
||||
primary_table_name = "",
|
||||
forms = c("repeating", "all")) {
|
||||
|
||||
# Process user input
|
||||
records <- process_user_input(records)
|
||||
records <- process_user_input(records)
|
||||
metadata <-
|
||||
as.data.frame(process_user_input(metadata))
|
||||
|
||||
|
|
@ -96,26 +96,27 @@ REDCap_split <- function(records,
|
|||
vars_in_data <- names(records)
|
||||
|
||||
# Process repeat instrument names to match the redcap naming
|
||||
if (is_repeated_longitudinal(records)){
|
||||
records$redcap_repeat_instrument <- clean_redcap_name(records$redcap_repeat_instrument)
|
||||
if (is_repeated_longitudinal(records)) {
|
||||
records$redcap_repeat_instrument <-
|
||||
clean_redcap_name(records$redcap_repeat_instrument)
|
||||
|
||||
# Match arg for forms
|
||||
forms <- match.arg(forms, c("repeating", "all"))
|
||||
# Match arg for forms
|
||||
forms <- match.arg(forms, c("repeating", "all"))
|
||||
|
||||
# Check to see if there were any repeating instruments
|
||||
if (forms == "repeating" &&
|
||||
# Check to see if there were any repeating instruments
|
||||
if (forms == "repeating" &&
|
||||
!"redcap_repeat_instrument" %in% vars_in_data) {
|
||||
stop("There are no repeating instruments in this dataset.")
|
||||
}
|
||||
stop("There are no repeating instruments in this dataset.")
|
||||
}
|
||||
|
||||
# Remove NAs from `redcap_repeat_instrument` (see issue #12)
|
||||
if (any(is.na(records$redcap_repeat_instrument))) {
|
||||
records$redcap_repeat_instrument <- ifelse(
|
||||
is.na(records$redcap_repeat_instrument),
|
||||
"",
|
||||
as.character(records$redcap_repeat_instrument)
|
||||
)
|
||||
}
|
||||
# Remove NAs from `redcap_repeat_instrument` (see issue #12)
|
||||
if (any(is.na(records$redcap_repeat_instrument))) {
|
||||
records$redcap_repeat_instrument <- ifelse(
|
||||
is.na(records$redcap_repeat_instrument),
|
||||
"",
|
||||
as.character(records$redcap_repeat_instrument)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
# Standardize variable names for metadata
|
||||
|
|
@ -144,8 +145,9 @@ REDCap_split <- function(records,
|
|||
if ("redcap_repeat_instrument" %in% vars_in_data) {
|
||||
# Variables to be at the beginning of each repeating instrument
|
||||
repeat_instrument_fields <- grep("^redcap_repeat.*",
|
||||
vars_in_data,
|
||||
value = TRUE)
|
||||
vars_in_data,
|
||||
value = TRUE
|
||||
)
|
||||
|
||||
# Identify the subtables in the data
|
||||
subtables <- unique(records$redcap_repeat_instrument)
|
||||
|
|
@ -169,35 +171,36 @@ REDCap_split <- function(records,
|
|||
# Delete the variables that are not relevant
|
||||
for (i in names(out)) {
|
||||
if (i == primary_table_name) {
|
||||
out_fields <- which(vars_in_data %in% c(universal_fields,
|
||||
fields[!fields[, 2] %in%
|
||||
subtables, 1]))
|
||||
out_fields <- which(vars_in_data %in% c(
|
||||
universal_fields,
|
||||
fields[!fields[, 2] %in%
|
||||
subtables, 1]
|
||||
))
|
||||
out[[primary_table_index]] <-
|
||||
out[[primary_table_index]][out_fields]
|
||||
|
||||
} else {
|
||||
out_fields <- which(vars_in_data %in% c(universal_fields,
|
||||
repeat_instrument_fields,
|
||||
fields[fields[, 2] == i, 1]))
|
||||
out_fields <- which(vars_in_data %in% c(
|
||||
universal_fields,
|
||||
repeat_instrument_fields,
|
||||
fields[fields[, 2] == i, 1]
|
||||
))
|
||||
out[[i]] <- out[[i]][out_fields]
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (forms == "all") {
|
||||
out <- c(split_non_repeating_forms(out[[primary_table_index]],
|
||||
universal_fields,
|
||||
fields[!fields[, 2] %in% subtables, ]),
|
||||
out[-primary_table_index])
|
||||
|
||||
out <- c(
|
||||
split_non_repeating_forms(
|
||||
out[[primary_table_index]],
|
||||
universal_fields,
|
||||
fields[!fields[, 2] %in% subtables, ]
|
||||
),
|
||||
out[-primary_table_index]
|
||||
)
|
||||
}
|
||||
|
||||
} else {
|
||||
out <- split_non_repeating_forms(records, universal_fields, fields)
|
||||
|
||||
}
|
||||
|
||||
out
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ ds2dd <-
|
|||
dd <- data.frame(matrix(ncol = length(metadata), nrow = ncol(ds)))
|
||||
colnames(dd) <- metadata
|
||||
|
||||
if (is.character(record.id) & !record.id %in% colnames(ds)) {
|
||||
if (is.character(record.id) && !record.id %in% colnames(ds)) {
|
||||
stop("Provided record.id is not a variable name in provided data set.")
|
||||
}
|
||||
|
||||
|
|
@ -59,7 +59,7 @@ ds2dd <-
|
|||
dd[, "field_name"] <-
|
||||
c(field.name[colsel], field.name[!colsel])
|
||||
|
||||
if (length(form.name) > 1 & length(form.name) != ncol(ds)) {
|
||||
if (length(form.name) > 1 && length(form.name) != ncol(ds)) {
|
||||
stop(
|
||||
"Provided form.name should be of length 1 (value is reused) or equal
|
||||
length as number of variables in data set."
|
||||
|
|
@ -67,7 +67,7 @@ ds2dd <-
|
|||
}
|
||||
dd[, "form_name"] <- form.name
|
||||
|
||||
if (length(field.type) > 1 & length(field.type) != ncol(ds)) {
|
||||
if (length(field.type) > 1 && length(field.type) != ncol(ds)) {
|
||||
stop(
|
||||
"Provided field.type should be of length 1 (value is reused) or equal
|
||||
length as number of variables in data set."
|
||||
|
|
|
|||
|
|
@ -1,4 +1,9 @@
|
|||
utils::globalVariables(c( "stats::setNames", "field_name", "field_type", "select_choices_or_calculations"))
|
||||
utils::globalVariables(c(
|
||||
"stats::setNames",
|
||||
"field_name",
|
||||
"field_type",
|
||||
"select_choices_or_calculations"
|
||||
))
|
||||
#' Try at determining which are true time only variables
|
||||
#'
|
||||
#' @description
|
||||
|
|
@ -18,10 +23,15 @@ utils::globalVariables(c( "stats::setNames", "field_name", "field_type", "se
|
|||
#' @examples
|
||||
#' data <- redcapcast_data
|
||||
#' data |> guess_time_only_filter()
|
||||
#' data |> guess_time_only_filter(validate = TRUE) |> lapply(head)
|
||||
guess_time_only_filter <- function(data, validate = FALSE, sel.pos = "[Tt]i[d(me)]", sel.neg = "[Dd]at[eo]") {
|
||||
#' data |>
|
||||
#' guess_time_only_filter(validate = TRUE) |>
|
||||
#' lapply(head)
|
||||
guess_time_only_filter <- function(data,
|
||||
validate = FALSE,
|
||||
sel.pos = "[Tt]i[d(me)]",
|
||||
sel.neg = "[Dd]at[eo]") {
|
||||
datetime_nms <- data |>
|
||||
lapply(\(x)any(c("POSIXct","hms") %in% class(x))) |>
|
||||
lapply(\(x) any(c("POSIXct", "hms") %in% class(x))) |>
|
||||
(\(x) names(data)[do.call(c, x)])()
|
||||
|
||||
time_only_log <- datetime_nms |> (\(x) {
|
||||
|
|
@ -42,12 +52,8 @@ guess_time_only_filter <- function(data, validate = FALSE, sel.pos = "[Tt]i[d(me
|
|||
}
|
||||
}
|
||||
|
||||
#' Correction based on time_only_filter function. Introduces new class for easier
|
||||
#' validation labelling.
|
||||
#' Correction based on time_only_filter function
|
||||
#'
|
||||
#' @description
|
||||
#' Dependens on the data class "hms" introduced with
|
||||
#' `guess_time_only_filter()` and converts these
|
||||
#'
|
||||
#' @param data data set
|
||||
#' @param ... arguments passed on to `guess_time_only_filter()`
|
||||
|
|
@ -119,8 +125,8 @@ hms2character <- function(data) {
|
|||
#' data set (imported .dta file with `haven::read_dta()`. Default is "label"
|
||||
#' @param field.validation manually specify field validation(s). Vector of
|
||||
#' length 1 or ncol(data). Default is NULL and `levels()` are used for factors
|
||||
#' or attribute `factor.labels.attr` for haven_labelled data set (imported .dta file with
|
||||
#' `haven::read_dta()`).
|
||||
#' or attribute `factor.labels.attr` for haven_labelled data set (imported .dta
|
||||
#' file with `haven::read_dta()`).
|
||||
#' @param metadata redcap metadata headings. Default is
|
||||
#' REDCapCAST:::metadata_names.
|
||||
#' @param validate.time Flag to validate guessed time columns
|
||||
|
|
@ -144,7 +150,7 @@ ds2dd_detailed <- function(data,
|
|||
form.name = NULL,
|
||||
field.type = NULL,
|
||||
field.label = NULL,
|
||||
field.label.attr ="label",
|
||||
field.label.attr = "label",
|
||||
field.validation = NULL,
|
||||
metadata = metadata_names,
|
||||
validate.time = FALSE,
|
||||
|
|
@ -164,7 +170,8 @@ ds2dd_detailed <- function(data,
|
|||
}
|
||||
|
||||
if (lapply(data, haven::is.labelled) |> (\(x)do.call(c, x))() |> any()) {
|
||||
message("Data seems to be imported with haven from a Stata (.dta) file and will be treated as such.")
|
||||
message("Data seems to be imported with haven from a Stata (.dta) file and
|
||||
will be treated as such.")
|
||||
data.source <- "dta"
|
||||
} else {
|
||||
data.source <- ""
|
||||
|
|
@ -172,18 +179,25 @@ ds2dd_detailed <- function(data,
|
|||
|
||||
## data classes
|
||||
|
||||
### Only keeps the first class, as time fields (POSIXct/POSIXt) has two classes
|
||||
### Only keeps the first class, as time fields (POSIXct/POSIXt) has two
|
||||
### classes
|
||||
if (data.source == "dta") {
|
||||
data_classes <-
|
||||
data |>
|
||||
haven::as_factor() |>
|
||||
time_only_correction(sel.pos = time.var.sel.pos, sel.neg = time.var.sel.neg) |>
|
||||
time_only_correction(
|
||||
sel.pos = time.var.sel.pos,
|
||||
sel.neg = time.var.sel.neg
|
||||
) |>
|
||||
lapply(\(x)class(x)[1]) |>
|
||||
(\(x)do.call(c, x))()
|
||||
} else {
|
||||
data_classes <-
|
||||
data |>
|
||||
time_only_correction(sel.pos = time.var.sel.pos, sel.neg = time.var.sel.neg) |>
|
||||
time_only_correction(
|
||||
sel.pos = time.var.sel.pos,
|
||||
sel.neg = time.var.sel.neg
|
||||
) |>
|
||||
lapply(\(x)class(x)[1]) |>
|
||||
(\(x)do.call(c, x))()
|
||||
}
|
||||
|
|
@ -204,7 +218,7 @@ ds2dd_detailed <- function(data,
|
|||
if (is.null(form.name)) {
|
||||
dd$form_name <- "data"
|
||||
} else {
|
||||
if (length(form.name) == 1 | length(form.name) == nrow(dd)) {
|
||||
if (length(form.name) == 1 || length(form.name) == nrow(dd)) {
|
||||
dd$form_name <- form.name
|
||||
} else {
|
||||
stop("Length of supplied 'form.name' has to be one (1) or ncol(data).")
|
||||
|
|
@ -229,9 +243,11 @@ ds2dd_detailed <- function(data,
|
|||
}
|
||||
|
||||
dd <-
|
||||
dd |> dplyr::mutate(field_label = dplyr::if_else(is.na(label), field_name, label))
|
||||
dd |> dplyr::mutate(field_label = dplyr::if_else(is.na(label),
|
||||
field_name, label
|
||||
))
|
||||
} else {
|
||||
if (length(field.label) == 1 | length(field.label) == nrow(dd)) {
|
||||
if (length(field.label) == 1 || length(field.label) == nrow(dd)) {
|
||||
dd$field_label <- field.label
|
||||
} else {
|
||||
stop("Length of supplied 'field.label' has to be one (1) or ncol(data).")
|
||||
|
|
@ -245,9 +261,11 @@ ds2dd_detailed <- function(data,
|
|||
dd$field_type <- "text"
|
||||
|
||||
dd <-
|
||||
dd |> dplyr::mutate(field_type = dplyr::if_else(data_classes == "factor", "radio", field_type))
|
||||
dd |> dplyr::mutate(field_type = dplyr::if_else(data_classes == "factor",
|
||||
"radio", field_type
|
||||
))
|
||||
} else {
|
||||
if (length(field.type) == 1 | length(field.type) == nrow(dd)) {
|
||||
if (length(field.type) == 1 || length(field.type) == nrow(dd)) {
|
||||
dd$field_type <- field.type
|
||||
} else {
|
||||
stop("Length of supplied 'field.type' has to be one (1) or ncol(data).")
|
||||
|
|
@ -271,10 +289,11 @@ ds2dd_detailed <- function(data,
|
|||
)
|
||||
)
|
||||
} else {
|
||||
if (length(field.validation) == 1 | length(field.validation) == nrow(dd)) {
|
||||
if (length(field.validation) == 1 || length(field.validation) == nrow(dd)) {
|
||||
dd$text_validation_type_or_show_slider_number <- field.validation
|
||||
} else {
|
||||
stop("Length of supplied 'field.validation' has to be one (1) or ncol(data).")
|
||||
stop("Length of supplied 'field.validation'
|
||||
has to be one (1) or ncol(data).")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -300,7 +319,13 @@ ds2dd_detailed <- function(data,
|
|||
## Re-factors to avoid confusion with missing levels
|
||||
## Assumes alle relevant levels are represented in the data
|
||||
re_fac <- factor(x)
|
||||
paste(paste(unique(as.numeric(re_fac)), levels(re_fac), sep = ", "), collapse = " | ")
|
||||
paste(
|
||||
paste(unique(as.numeric(re_fac)),
|
||||
levels(re_fac),
|
||||
sep = ", "
|
||||
),
|
||||
collapse = " | "
|
||||
)
|
||||
} else {
|
||||
NA
|
||||
}
|
||||
|
|
@ -319,7 +344,10 @@ ds2dd_detailed <- function(data,
|
|||
|
||||
list(
|
||||
data = data |>
|
||||
time_only_correction(sel.pos = time.var.sel.pos, sel.neg = time.var.sel.neg) |>
|
||||
time_only_correction(
|
||||
sel.pos = time.var.sel.pos,
|
||||
sel.neg = time.var.sel.neg
|
||||
) |>
|
||||
hms2character() |>
|
||||
(\(x)stats::setNames(x, tolower(names(x))))(),
|
||||
meta = dd
|
||||
|
|
@ -333,11 +361,16 @@ ds2dd_detailed <- function(data,
|
|||
#' @param ls output list from `ds2dd_detailed()`
|
||||
#'
|
||||
#' @return list with `REDCapR::redcap_write()` results
|
||||
mark_complete <- function(upload, ls){
|
||||
mark_complete <- function(upload, ls) {
|
||||
data <- ls$data
|
||||
meta <- ls$meta
|
||||
forms <- unique(meta$form_name)
|
||||
cbind(data[[1]][data[[1]] %in% upload$affected_ids],
|
||||
data.frame(matrix(2,ncol=length(forms),nrow=upload$records_affected_count))) |>
|
||||
stats::setNames(c(names(data)[1],paste0(forms,"_complete")))
|
||||
cbind(
|
||||
data[[1]][data[[1]] %in% upload$affected_ids],
|
||||
data.frame(matrix(2,
|
||||
ncol = length(forms),
|
||||
nrow = upload$records_affected_count
|
||||
))
|
||||
) |>
|
||||
stats::setNames(c(names(data)[1], paste0(forms, "_complete")))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
#' Retrieve project API key if stored, if not, set and retrieve
|
||||
#'
|
||||
#' @param key.name character vector of key name
|
||||
|
|
@ -26,7 +25,7 @@ get_api_key <- function(key.name) {
|
|||
#'
|
||||
#' @return data.frame or list depending on widen.data
|
||||
#' @export
|
||||
easy_redcap <- function(project.name, widen.data=TRUE, uri, ...) {
|
||||
easy_redcap <- function(project.name, widen.data = TRUE, uri, ...) {
|
||||
key <- get_api_key(key.name = paste0(project.name, "_REDCAP_API"))
|
||||
|
||||
out <- read_redcap_tables(
|
||||
|
|
@ -35,7 +34,7 @@ easy_redcap <- function(project.name, widen.data=TRUE, uri, ...) {
|
|||
...
|
||||
)
|
||||
|
||||
if (widen.data){
|
||||
if (widen.data) {
|
||||
out <- out |> redcap_wider()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,4 +20,3 @@
|
|||
#' }
|
||||
#' @usage data(mtcars_redcap)
|
||||
"mtcars_redcap"
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
process_user_input <- function (x) {
|
||||
process_user_input <- function(x) {
|
||||
UseMethod("process_user_input", x)
|
||||
}
|
||||
|
||||
|
|
@ -30,10 +30,8 @@ process_user_input.character <- function(x, ...) {
|
|||
}
|
||||
|
||||
jsonlite::fromJSON(x)
|
||||
|
||||
}
|
||||
|
||||
process_user_input.response <- function(x, ...) {
|
||||
process_user_input(rawToChar(x$content))
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,20 +1,22 @@
|
|||
#' Convenience function to download complete instrument, using token storage in keyring.
|
||||
#' Convenience function to download complete instrument, using token storage
|
||||
#' in keyring.
|
||||
#'
|
||||
#' @param key key name in standard keyring for token retrieval.
|
||||
#' @param uri REDCap database API uri
|
||||
#' @param instrument instrument name
|
||||
#' @param raw_or_label raw or label passed to `REDCapR::redcap_read()`
|
||||
#' @param id_name id variable name. Default is "record_id".
|
||||
#' @param records specify the records to download. Index numbers. Numeric vector.
|
||||
#' @param records specify the records to download. Index numbers.
|
||||
#' Numeric vector.
|
||||
#'
|
||||
#' @return data.frame
|
||||
#' @export
|
||||
read_redcap_instrument <- function(key,
|
||||
uri,
|
||||
instrument,
|
||||
raw_or_label = "raw",
|
||||
id_name = "record_id",
|
||||
records = NULL) {
|
||||
uri,
|
||||
instrument,
|
||||
raw_or_label = "raw",
|
||||
id_name = "record_id",
|
||||
records = NULL) {
|
||||
REDCapCAST::read_redcap_tables(
|
||||
records = records,
|
||||
uri = uri, token = keyring::key_get(key),
|
||||
|
|
|
|||
|
|
@ -38,7 +38,8 @@ read_redcap_tables <- function(uri,
|
|||
fields_test <- fields %in% unique(m$field_name)
|
||||
|
||||
if (any(!fields_test)) {
|
||||
print(paste0("The following field names are invalid: ", paste(fields[!fields_test], collapse = ", "), "."))
|
||||
print(paste0("The following field names are invalid: ",
|
||||
paste(fields[!fields_test], collapse = ", "), "."))
|
||||
stop("Not all supplied field names are valid")
|
||||
}
|
||||
}
|
||||
|
|
@ -48,7 +49,8 @@ read_redcap_tables <- function(uri,
|
|||
forms_test <- forms %in% unique(m$form_name)
|
||||
|
||||
if (any(!forms_test)) {
|
||||
print(paste0("The following form names are invalid: ", paste(forms[!forms_test], collapse = ", "), "."))
|
||||
print(paste0("The following form names are invalid: ",
|
||||
paste(forms[!forms_test], collapse = ", "), "."))
|
||||
stop("Not all supplied form names are valid")
|
||||
}
|
||||
}
|
||||
|
|
@ -62,7 +64,8 @@ read_redcap_tables <- function(uri,
|
|||
event_test <- events %in% unique(arm_event_inst$data$unique_event_name)
|
||||
|
||||
if (any(!event_test)) {
|
||||
print(paste0("The following event names are invalid: ", paste(events[!event_test], collapse = ", "), "."))
|
||||
print(paste0("The following event names are invalid: ",
|
||||
paste(events[!event_test], collapse = ", "), "."))
|
||||
stop("Not all supplied event names are valid")
|
||||
}
|
||||
}
|
||||
|
|
@ -89,15 +92,12 @@ read_redcap_tables <- function(uri,
|
|||
m <- focused_metadata(m, names(d))
|
||||
|
||||
|
||||
# Splitting
|
||||
out <- REDCap_split(d,
|
||||
m,
|
||||
forms = split_forms,
|
||||
primary_table_name = ""
|
||||
)
|
||||
|
||||
sanitize_split(out)
|
||||
# Splitting
|
||||
out <- REDCap_split(d,
|
||||
m,
|
||||
forms = split_forms,
|
||||
primary_table_name = ""
|
||||
)
|
||||
|
||||
sanitize_split(out)
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
189
R/redcap_wider.R
189
R/redcap_wider.R
|
|
@ -1,6 +1,8 @@
|
|||
utils::globalVariables(c("redcap_wider",
|
||||
"event.glue",
|
||||
"inst.glue"))
|
||||
utils::globalVariables(c(
|
||||
"redcap_wider",
|
||||
"event.glue",
|
||||
"inst.glue"
|
||||
))
|
||||
|
||||
#' @title Redcap Wider
|
||||
#' @description Converts a list of REDCap data frames from long to wide format.
|
||||
|
|
@ -16,42 +18,65 @@ utils::globalVariables(c("redcap_wider",
|
|||
#'
|
||||
#' @examples
|
||||
#' # Longitudinal
|
||||
#' list1 <- list(data.frame(record_id = c(1,2,1,2),
|
||||
#' redcap_event_name = c("baseline", "baseline", "followup", "followup"),
|
||||
#' age = c(25,26,27,28)),
|
||||
#' data.frame(record_id = c(1,2),
|
||||
#' redcap_event_name = c("baseline", "baseline"),
|
||||
#' gender = c("male", "female")))
|
||||
#' list1 <- list(
|
||||
#' data.frame(
|
||||
#' record_id = c(1, 2, 1, 2),
|
||||
#' redcap_event_name = c("baseline", "baseline", "followup", "followup"),
|
||||
#' age = c(25, 26, 27, 28)
|
||||
#' ),
|
||||
#' data.frame(
|
||||
#' record_id = c(1, 2),
|
||||
#' redcap_event_name = c("baseline", "baseline"),
|
||||
#' gender = c("male", "female")
|
||||
#' )
|
||||
#' )
|
||||
#' redcap_wider(list1)
|
||||
#' # Simpel with two instruments
|
||||
#' list2 <- list(data.frame(record_id = c(1,2),
|
||||
#' age = c(25,26)),
|
||||
#' data.frame(record_id = c(1,2),
|
||||
#' gender = c("male", "female")))
|
||||
#' list2 <- list(
|
||||
#' data.frame(
|
||||
#' record_id = c(1, 2),
|
||||
#' age = c(25, 26)
|
||||
#' ),
|
||||
#' data.frame(
|
||||
#' record_id = c(1, 2),
|
||||
#' gender = c("male", "female")
|
||||
#' )
|
||||
#' )
|
||||
#' redcap_wider(list2)
|
||||
#' # Simple with single instrument
|
||||
#' list3 <- list(data.frame(record_id = c(1,2),
|
||||
#' age = c(25,26)))
|
||||
#' list3 <- list(data.frame(
|
||||
#' record_id = c(1, 2),
|
||||
#' age = c(25, 26)
|
||||
#' ))
|
||||
#' redcap_wider(list3)
|
||||
#' # Longitudinal with repeatable instruments
|
||||
#' list4 <- list(data.frame(record_id = c(1,2,1,2),
|
||||
#' redcap_event_name = c("baseline", "baseline", "followup", "followup"),
|
||||
#' age = c(25,26,27,28)),
|
||||
#' data.frame(record_id = c(1,1,1,1,2,2,2,2),
|
||||
#' redcap_event_name = c("baseline", "baseline", "followup", "followup",
|
||||
#' "baseline", "baseline", "followup", "followup"),
|
||||
#' redcap_repeat_instrument = "walk",
|
||||
#' redcap_repeat_instance=c(1,2,1,2,1,2,1,2),
|
||||
#' dist = c(40, 32, 25, 33, 28, 24, 23, 36)),
|
||||
#' data.frame(record_id = c(1,2),
|
||||
#' redcap_event_name = c("baseline", "baseline"),
|
||||
#' gender = c("male", "female")))
|
||||
#'redcap_wider(list4)
|
||||
#' list4 <- list(
|
||||
#' data.frame(
|
||||
#' record_id = c(1, 2, 1, 2),
|
||||
#' redcap_event_name = c("baseline", "baseline", "followup", "followup"),
|
||||
#' age = c(25, 26, 27, 28)
|
||||
#' ),
|
||||
#' data.frame(
|
||||
#' record_id = c(1, 1, 1, 1, 2, 2, 2, 2),
|
||||
#' redcap_event_name = c(
|
||||
#' "baseline", "baseline", "followup", "followup",
|
||||
#' "baseline", "baseline", "followup", "followup"
|
||||
#' ),
|
||||
#' redcap_repeat_instrument = "walk",
|
||||
#' redcap_repeat_instance = c(1, 2, 1, 2, 1, 2, 1, 2),
|
||||
#' dist = c(40, 32, 25, 33, 28, 24, 23, 36)
|
||||
#' ),
|
||||
#' data.frame(
|
||||
#' record_id = c(1, 2),
|
||||
#' redcap_event_name = c("baseline", "baseline"),
|
||||
#' gender = c("male", "female")
|
||||
#' )
|
||||
#' )
|
||||
#' redcap_wider(list4)
|
||||
redcap_wider <-
|
||||
function(data,
|
||||
event.glue = "{.value}_{redcap_event_name}",
|
||||
inst.glue = "{.value}_{redcap_repeat_instance}") {
|
||||
|
||||
if (!is_repeated_longitudinal(data)) {
|
||||
if (is.list(data)) {
|
||||
if (length(data) == 1) {
|
||||
|
|
@ -59,69 +84,65 @@ redcap_wider <-
|
|||
} else {
|
||||
out <- data |> purrr::reduce(dplyr::left_join)
|
||||
}
|
||||
} else if (is.data.frame(data)){
|
||||
} else if (is.data.frame(data)) {
|
||||
out <- data
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
id.name <- do.call(c, lapply(data, names))[[1]]
|
||||
|
||||
id.name <- do.call(c, lapply(data, names))[[1]]
|
||||
l <- lapply(data, function(i) {
|
||||
rep_inst <- "redcap_repeat_instrument" %in% names(i)
|
||||
|
||||
l <- lapply(data, function(i) {
|
||||
rep_inst <- "redcap_repeat_instrument" %in% names(i)
|
||||
|
||||
if (rep_inst) {
|
||||
k <- lapply(split(i, f = i[[id.name]]), function(j) {
|
||||
cname <- colnames(j)
|
||||
vals <-
|
||||
cname[!cname %in% c(
|
||||
id.name,
|
||||
"redcap_event_name",
|
||||
"redcap_repeat_instrument",
|
||||
"redcap_repeat_instance"
|
||||
)]
|
||||
s <- tidyr::pivot_wider(
|
||||
j,
|
||||
names_from = "redcap_repeat_instance",
|
||||
values_from = all_of(vals),
|
||||
names_glue = inst.glue
|
||||
)
|
||||
s[!colnames(s) %in% c("redcap_repeat_instrument")]
|
||||
})
|
||||
i <- Reduce(dplyr::bind_rows, k)
|
||||
}
|
||||
|
||||
event <- "redcap_event_name" %in% names(i)
|
||||
|
||||
if (event) {
|
||||
event.n <- length(unique(i[["redcap_event_name"]])) > 1
|
||||
|
||||
i[["redcap_event_name"]] <-
|
||||
gsub(" ", "_", tolower(i[["redcap_event_name"]]))
|
||||
|
||||
if (event.n) {
|
||||
cname <- colnames(i)
|
||||
vals <- cname[!cname %in% c(id.name, "redcap_event_name")]
|
||||
|
||||
s <- tidyr::pivot_wider(
|
||||
i,
|
||||
names_from = "redcap_event_name",
|
||||
values_from = all_of(vals),
|
||||
names_glue = event.glue
|
||||
)
|
||||
s[colnames(s) != "redcap_event_name"]
|
||||
} else {
|
||||
i[colnames(i) != "redcap_event_name"]
|
||||
}
|
||||
} else {
|
||||
i
|
||||
if (rep_inst) {
|
||||
k <- lapply(split(i, f = i[[id.name]]), function(j) {
|
||||
cname <- colnames(j)
|
||||
vals <-
|
||||
cname[!cname %in% c(
|
||||
id.name,
|
||||
"redcap_event_name",
|
||||
"redcap_repeat_instrument",
|
||||
"redcap_repeat_instance"
|
||||
)]
|
||||
s <- tidyr::pivot_wider(
|
||||
j,
|
||||
names_from = "redcap_repeat_instance",
|
||||
values_from = all_of(vals),
|
||||
names_glue = inst.glue
|
||||
)
|
||||
s[!colnames(s) %in% c("redcap_repeat_instrument")]
|
||||
})
|
||||
i <- Reduce(dplyr::bind_rows, k)
|
||||
}
|
||||
})
|
||||
|
||||
out <- data.frame(Reduce(f = dplyr::full_join, x = l))
|
||||
event <- "redcap_event_name" %in% names(i)
|
||||
|
||||
if (event) {
|
||||
event.n <- length(unique(i[["redcap_event_name"]])) > 1
|
||||
|
||||
i[["redcap_event_name"]] <-
|
||||
gsub(" ", "_", tolower(i[["redcap_event_name"]]))
|
||||
|
||||
if (event.n) {
|
||||
cname <- colnames(i)
|
||||
vals <- cname[!cname %in% c(id.name, "redcap_event_name")]
|
||||
|
||||
s <- tidyr::pivot_wider(
|
||||
i,
|
||||
names_from = "redcap_event_name",
|
||||
values_from = all_of(vals),
|
||||
names_glue = event.glue
|
||||
)
|
||||
s[colnames(s) != "redcap_event_name"]
|
||||
} else {
|
||||
i[colnames(i) != "redcap_event_name"]
|
||||
}
|
||||
} else {
|
||||
i
|
||||
}
|
||||
})
|
||||
|
||||
out <- data.frame(Reduce(f = dplyr::full_join, x = l))
|
||||
}
|
||||
|
||||
out
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -33,5 +33,3 @@
|
|||
#' }
|
||||
#' @usage data(redcapcast_data)
|
||||
"redcapcast_data"
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -9,9 +9,11 @@
|
|||
#' \item{section_header}{section_header, character}
|
||||
#' \item{field_type}{field_type, character}
|
||||
#' \item{field_label}{field_label, character}
|
||||
#' \item{select_choices_or_calculations}{select_choices_or_calculations, character}
|
||||
#' \item{select_choices_or_calculations}
|
||||
#' {select_choices_or_calculations, character}
|
||||
#' \item{field_note}{field_note, character}
|
||||
#' \item{text_validation_type_or_show_slider_number}{text_validation_type_or_show_slider_number, character}
|
||||
#' \item{text_validation_type_or_show_slider_number}
|
||||
#' {text_validation_type_or_show_slider_number, character}
|
||||
#' \item{text_validation_min}{text_validation_min, character}
|
||||
#' \item{text_validation_max}{text_validation_max, character}
|
||||
#' \item{identifier}{identifier, character}
|
||||
|
|
@ -25,5 +27,3 @@
|
|||
#' }
|
||||
#' @usage data(redcapcast_meta)
|
||||
"redcapcast_meta"
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -14,8 +14,7 @@ server_factory <- function() {
|
|||
#' @export
|
||||
ui_factory <- function() {
|
||||
# require(ggplot2)
|
||||
source(here::here("app/ui.R"))
|
||||
|
||||
source(here::here("app/ui.R"))
|
||||
}
|
||||
|
||||
#' Launch the included Shiny-app for database casting and upload
|
||||
|
|
@ -46,7 +45,7 @@ shiny_cast <- function() {
|
|||
#' @examples
|
||||
#' # deploy_shiny
|
||||
#'
|
||||
deploy_shiny <- function(path=here::here("app/"), name.app="shiny_cast"){
|
||||
deploy_shiny <- function(path = here::here("app/"), name.app = "shiny_cast") {
|
||||
# Connecting
|
||||
rsconnect::setAccountInfo(
|
||||
name = "cognitiveindex",
|
||||
|
|
@ -55,5 +54,5 @@ deploy_shiny <- function(path=here::here("app/"), name.app="shiny_cast"){
|
|||
)
|
||||
|
||||
# Deploying
|
||||
rsconnect::deployApp(appDir = path,lint = TRUE,appName = name.app,)
|
||||
rsconnect::deployApp(appDir = path, lint = TRUE, appName = name.app, )
|
||||
}
|
||||
|
|
|
|||
25
R/utils.r
25
R/utils.r
|
|
@ -128,9 +128,11 @@ sanitize_split <- function(l,
|
|||
"redcap_repeat_instrument",
|
||||
"redcap_repeat_instance"
|
||||
)) {
|
||||
generic.names <- c(get_id_name(l),
|
||||
generic.names,
|
||||
paste0(names(l), "_complete"))
|
||||
generic.names <- c(
|
||||
get_id_name(l),
|
||||
generic.names,
|
||||
paste0(names(l), "_complete")
|
||||
)
|
||||
|
||||
lapply(l, function(i) {
|
||||
if (ncol(i) > 2) {
|
||||
|
|
@ -334,7 +336,8 @@ split_non_repeating_forms <-
|
|||
#' @export
|
||||
#'
|
||||
#' @examples
|
||||
#' test <- c("12 months follow-up", "3 steps", "mRS 6 weeks", "Counting to 231 now")
|
||||
#' test <- c("12 months follow-up", "3 steps", "mRS 6 weeks",
|
||||
#' "Counting to 231 now")
|
||||
#' strsplitx(test, "[0-9]", type = "around")
|
||||
strsplitx <- function(x,
|
||||
split,
|
||||
|
|
@ -403,7 +406,8 @@ d2w <- function(x, lang = "en", neutrum = FALSE, everything = FALSE) {
|
|||
# In Danish the written 1 depends on the counted word
|
||||
if (neutrum) nt <- "t" else nt <- "n"
|
||||
|
||||
# A sapply() call with nested lapply() to handle vectors, data.frames and lists
|
||||
# A sapply() call with nested lapply() to handle vectors, data.frames
|
||||
# and lists
|
||||
convert <- function(x, lang, neutrum) {
|
||||
zero_nine <- data.frame(
|
||||
num = 0:9,
|
||||
|
|
@ -503,7 +507,9 @@ is_repeated_longitudinal <- function(data, generics = c(
|
|||
#' @examples
|
||||
#' file_extension(list.files(here::here(""))[[2]])[[1]]
|
||||
file_extension <- function(filenames) {
|
||||
sub(pattern = "^(.*\\.|[^.]+)(?=[^.]*)", replacement = "", filenames, perl = TRUE)
|
||||
sub(pattern = "^(.*\\.|[^.]+)(?=[^.]*)", replacement = "",
|
||||
filenames,
|
||||
perl = TRUE)
|
||||
}
|
||||
|
||||
#' Flexible file import based on extension
|
||||
|
|
@ -516,17 +522,16 @@ file_extension <- function(filenames) {
|
|||
#'
|
||||
#' @examples
|
||||
#' read_input("https://raw.githubusercontent.com/agdamsbo/cognitive.index.lookup/main/data/sample.csv")
|
||||
read_input <- function(file, consider.na= c("NA", '""',"")){
|
||||
|
||||
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)
|
||||
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"){
|
||||
} else if (ext == "dta") {
|
||||
df <- haven::read_dta(file = file)
|
||||
} else {
|
||||
stop("Input file format has to be either '.csv', '.xls' or '.xlsx'")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue