mirror of
https://github.com/agdamsbo/REDCapCAST.git
synced 2025-01-31 19:21:55 +01:00
cleaning and fixes for a minor release
This commit is contained in:
parent
7d82eeebd4
commit
8d20901636
@ -1,6 +1,6 @@
|
||||
Package: REDCapCAST
|
||||
Title: REDCap Metadata Casting and Castellated Data Handling
|
||||
Version: 24.12.1
|
||||
Version: 25.1.1
|
||||
Authors@R: c(
|
||||
person("Andreas Gammelgaard", "Damsbo", email = "agdamsbo@clin.au.dk",
|
||||
role = c("aut", "cre"),comment = c(ORCID = "0000-0002-7559-1154")),
|
||||
@ -65,9 +65,9 @@ Imports:
|
||||
gtsummary
|
||||
Collate:
|
||||
'REDCapCAST-package.R'
|
||||
'utils.r'
|
||||
'process_user_input.r'
|
||||
'REDCap_split.r'
|
||||
'utils.R'
|
||||
'process_user_input.R'
|
||||
'REDCap_split.R'
|
||||
'as_factor.R'
|
||||
'doc2dd.R'
|
||||
'ds2dd_detailed.R'
|
||||
|
@ -28,6 +28,7 @@ export(clean_redcap_name)
|
||||
export(compact_vec)
|
||||
export(create_html_table)
|
||||
export(create_instrument_meta)
|
||||
export(cut_string_length)
|
||||
export(d2w)
|
||||
export(doc2dd)
|
||||
export(ds2dd)
|
||||
|
14
NEWS.md
14
NEWS.md
@ -1,18 +1,24 @@
|
||||
# REDCapCAST 24.12.2
|
||||
# REDCapCAST 25.1.1
|
||||
|
||||
The newly introduced extension of `forcats::fct_drop()` has been corrected to work as intended as a method.
|
||||
|
||||
Conversion of column names to `field_names` are aligning better with REDCap naming.
|
||||
|
||||
Shorten variable names above 100 characters (REDCap criteria; note recommended variable name length is <26)
|
||||
|
||||
Fixed a params conflict in easy_redcap() when specifying raw_or_label.
|
||||
|
||||
# REDCapCAST 24.12.1
|
||||
|
||||
This release attempts to solve problems hosting the shiny_cast app, while also implementing functions to preserve as much meta data as possible from the REDCap database when exporting data.
|
||||
|
||||
The hosting on shinyapps.io has given a lot of trouble recently. Modified package structure a little around the `shiny_cast()`, to accommodate an alternative hosting approach with all package functions included in a script instead of requiring the package.
|
||||
|
||||
* NEW: A new option to `raw_or_label` in `read_readcap_tables()` has been added: "both". Get raw values with REDCap labels applied as labels. Use `as_factor()` to format factors with original labels and use the `gtsummary` package to easily get beautiful tables with original labels from REDCap. Use `fct_drop()` to drop empty levels.
|
||||
* NEW: A new option to `raw_or_label` in `read_redcap_tables()` has been added: "both". Get raw values with REDCap labels applied as labels. Use `as_factor()` to format factors with original labels and use the `gtsummary` package to easily get beautiful tables with original labels from REDCap. Use `fct_drop()` to drop empty levels.
|
||||
|
||||
* NEW: fct_drop() has been added with an extension to `forcats::fct_drop()`, that works across data.frames. Use as `fct_drop()`.
|
||||
|
||||
* CHANGE: the default data export method of `easy_redcap()` has been changed to use the new labelled data export with `read_readcap_tables()`.
|
||||
* CHANGE: the default data export method of `easy_redcap()` has been changed to use the new labelled data export with `read_redcap_tables()`.
|
||||
|
||||
# REDCapCAST 24.11.3
|
||||
|
||||
@ -165,7 +171,7 @@ The main goal this package is to keep the option to only export a defined subset
|
||||
|
||||
### Functions:
|
||||
|
||||
* `read_redcap_tables()` **NEW**: this function is mainly an implementation of the combined use of `REDCapR::readcap_read()` and `REDCap_split()` to maintain the focused nature of `REDCapR::readcap_read()`, to only download the specified data. Also implements tests of valid form names and event names. The usual fall-back solution was to get all data.
|
||||
* `read_redcap_tables()` **NEW**: this function is mainly an implementation of the combined use of `REDCapR::redcap_read()` and `REDCap_split()` to maintain the focused nature of `REDCapR::redcap_read()`, to only download the specified data. Also implements tests of valid form names and event names. The usual fall-back solution was to get all data.
|
||||
|
||||
* `redcap_wider()` **NEW**: this function pivots the long data frames from `read_redcap_tables()` using `tidyr::pivot_wider()`.
|
||||
|
||||
|
@ -80,7 +80,7 @@
|
||||
#' \item \code{'all'}: a data.frame for each instrument, regardless of
|
||||
#' whether it is a repeating instrument or not.
|
||||
#' }
|
||||
#' @include process_user_input.r utils.r
|
||||
#' @include process_user_input.R utils.R
|
||||
#' @export
|
||||
REDCap_split <- function(records,
|
||||
metadata,
|
||||
|
@ -1,5 +1,4 @@
|
||||
utils::globalVariables(c(
|
||||
"stats::setNames",
|
||||
"field_name",
|
||||
"field_type",
|
||||
"select_choices_or_calculations",
|
||||
@ -247,7 +246,7 @@ ds2dd <-
|
||||
#' form.name = sample(c("b", "c"), size = 6, replace = TRUE, prob = rep(.5, 2))
|
||||
#' ) |>
|
||||
#' purrr::pluck("meta")
|
||||
#' mtcars |> ds2dd_detailed(add.auto.id = TRUE)
|
||||
#' mtcars |> numchar2fct() |> ds2dd_detailed(add.auto.id = TRUE)
|
||||
#'
|
||||
#' ## Using column name suffix to carry form name
|
||||
#' data <- iris |>
|
||||
@ -269,6 +268,10 @@ ds2dd_detailed <- function(data,
|
||||
metadata = names(REDCapCAST::redcapcast_meta),
|
||||
convert.logicals = TRUE) {
|
||||
|
||||
short_names <- colnames(data) |> lapply(\(.x) cut_string_length(.x,l=90)) |> purrr::reduce(c)
|
||||
|
||||
data <- stats::setNames(data,short_names)
|
||||
|
||||
if (convert.logicals) {
|
||||
data <- data |>
|
||||
## Converts logical to factor, which overwrites attributes
|
||||
@ -294,7 +297,6 @@ ds2dd_detailed <- function(data,
|
||||
dplyr::tibble()
|
||||
|
||||
## form_name and field_name
|
||||
|
||||
if (!is.null(form.sep)) {
|
||||
if (form.sep != "") {
|
||||
parts <- strsplit(names(data), split = form.sep)
|
||||
@ -313,11 +315,14 @@ ds2dd_detailed <- function(data,
|
||||
dd$field_name <- tolower(dd$field_name)
|
||||
} else {
|
||||
dd$form_name <- "data"
|
||||
dd$field_name <- gsub(" ", "_", tolower(colnames(data)))
|
||||
|
||||
# dd$field_name <- gsub(" ", "_", tolower(colnames(data)))
|
||||
dd$field_name <- clean_redcap_name(colnames(data))
|
||||
}
|
||||
} else {
|
||||
## if no form name prefix, the colnames are used as field_names
|
||||
dd$field_name <- gsub(" ", "_", tolower(colnames(data)))
|
||||
# dd$field_name <- gsub(" ", "_", tolower(colnames(data)))
|
||||
dd$field_name <- clean_redcap_name(colnames(data))
|
||||
|
||||
if (is.null(form.name)) {
|
||||
dd$form_name <- "data"
|
||||
@ -425,7 +430,14 @@ ds2dd_detailed <- function(data,
|
||||
out <- list(
|
||||
data = data |>
|
||||
hms2character() |>
|
||||
stats::setNames(dd$field_name),
|
||||
stats::setNames(dd$field_name) |>
|
||||
lapply(\(.x){
|
||||
if (identical("factor",class(.x))){
|
||||
as.numeric(.x)
|
||||
} else {
|
||||
.x
|
||||
}
|
||||
}) |> dplyr::bind_cols(),
|
||||
meta = dd
|
||||
)
|
||||
|
||||
|
@ -28,6 +28,9 @@ get_api_key <- function(key.name, ...) {
|
||||
#' \link[keyring]{key_set}, using the default keyring)
|
||||
#' @param widen.data argument to widen the exported data
|
||||
#' @param uri REDCap database API uri
|
||||
#' @param raw_or_label argument passed on to
|
||||
#' \link[REDCapCAST]{read_redcap_tables}. Default is "both" to get labelled
|
||||
#' data.
|
||||
#' @param ... arguments passed on to \link[REDCapCAST]{read_redcap_tables}.
|
||||
#'
|
||||
#' @return data.frame or list depending on widen.data
|
||||
@ -35,16 +38,22 @@ get_api_key <- function(key.name, ...) {
|
||||
#'
|
||||
#' @examples
|
||||
#' \dontrun{
|
||||
#' easy_redcap("My_new_project",fields=c("record_id","age","hypertension"))
|
||||
#' easy_redcap("My_new_project", fields = c("record_id", "age", "hypertension"))
|
||||
#' }
|
||||
easy_redcap <- function(project.name, widen.data = TRUE, uri, ...) {
|
||||
key <- get_api_key(key.name = paste0(project.name, "_REDCAP_API"),
|
||||
prompt = "Provide REDCap API key:")
|
||||
easy_redcap <- function(project.name,
|
||||
widen.data = TRUE,
|
||||
uri,
|
||||
raw_or_label = "both",
|
||||
...) {
|
||||
key <- get_api_key(
|
||||
key.name = paste0(project.name, "_REDCAP_API"),
|
||||
prompt = "Provide REDCap API key:"
|
||||
)
|
||||
|
||||
out <- read_redcap_tables(
|
||||
uri = uri,
|
||||
token = key,
|
||||
raw_or_label = "both",
|
||||
raw_or_label = raw_or_label,
|
||||
...
|
||||
)
|
||||
|
||||
|
@ -31,7 +31,7 @@
|
||||
#'
|
||||
#' @return list of instruments
|
||||
#' @importFrom REDCapR redcap_metadata_read redcap_read redcap_event_instruments
|
||||
#' @include utils.r
|
||||
#' @include utils.R
|
||||
#' @export
|
||||
#'
|
||||
#' @examples
|
||||
|
23
R/utils.r
23
R/utils.r
@ -97,7 +97,10 @@ focused_metadata <- function(metadata, vars_in_data) {
|
||||
#' @return vector or data frame, same format as input
|
||||
#' @export
|
||||
#'
|
||||
#' @examples
|
||||
#' "Research!, ne:ws? and c;l-.ls" |> clean_redcap_name()
|
||||
clean_redcap_name <- function(x) {
|
||||
gsub("[,.;:?!@]","",
|
||||
gsub(
|
||||
" ", "_",
|
||||
gsub(
|
||||
@ -108,6 +111,7 @@ clean_redcap_name <- function(x) {
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -518,3 +522,22 @@ dummy_fun <- function(...){
|
||||
gtsummary::add_difference()
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
#' Cut string to desired length
|
||||
#'
|
||||
#' @param data data
|
||||
#' @param l length
|
||||
#'
|
||||
#' @returns character string of length l
|
||||
#' @export
|
||||
#'
|
||||
#' @examples
|
||||
#' "length" |> cut_string_length(l=3)
|
||||
cut_string_length <- function(data,l=100){
|
||||
if (nchar(data)>=l){
|
||||
substr(data,1,l)
|
||||
} else {
|
||||
data
|
||||
}
|
||||
}
|
||||
|
@ -68,6 +68,7 @@ natively
|
||||
ncol
|
||||
og
|
||||
param
|
||||
params
|
||||
pegeler
|
||||
perl
|
||||
pos
|
||||
|
@ -5,6 +5,6 @@ account: agdamsbo
|
||||
server: shinyapps.io
|
||||
hostUrl: https://api.shinyapps.io/v1
|
||||
appId: 11351429
|
||||
bundleId: 9461113
|
||||
bundleId: 9642648
|
||||
url: https://agdamsbo.shinyapps.io/redcapcast/
|
||||
version: 1
|
||||
|
@ -1,5 +1,5 @@
|
||||
% Generated by roxygen2: do not edit by hand
|
||||
% Please edit documentation in R/REDCap_split.r
|
||||
% Please edit documentation in R/REDCap_split.R
|
||||
\name{REDCap_split}
|
||||
\alias{REDCap_split}
|
||||
\title{Split REDCap repeating instruments table into multiple tables}
|
||||
|
@ -1,5 +1,5 @@
|
||||
% Generated by roxygen2: do not edit by hand
|
||||
% Please edit documentation in R/utils.r
|
||||
% Please edit documentation in R/utils.R
|
||||
\name{clean_redcap_name}
|
||||
\alias{clean_redcap_name}
|
||||
\title{clean_redcap_name}
|
||||
@ -17,3 +17,6 @@ Stepwise removal on non-alphanumeric characters, trailing white space,
|
||||
substitutes spaces for underscores and converts to lower case.
|
||||
Trying to make up for different naming conventions.
|
||||
}
|
||||
\examples{
|
||||
"Research!, ne:ws? and c;l-.ls" |> clean_redcap_name()
|
||||
}
|
||||
|
22
man/cut_string_length.Rd
Normal file
22
man/cut_string_length.Rd
Normal file
@ -0,0 +1,22 @@
|
||||
% Generated by roxygen2: do not edit by hand
|
||||
% Please edit documentation in R/utils.R
|
||||
\name{cut_string_length}
|
||||
\alias{cut_string_length}
|
||||
\title{Cut string to desired length}
|
||||
\usage{
|
||||
cut_string_length(data, l = 100)
|
||||
}
|
||||
\arguments{
|
||||
\item{data}{data}
|
||||
|
||||
\item{l}{length}
|
||||
}
|
||||
\value{
|
||||
character string of length l
|
||||
}
|
||||
\description{
|
||||
Cut string to desired length
|
||||
}
|
||||
\examples{
|
||||
"length" |> cut_string_length(l=3)
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
% Generated by roxygen2: do not edit by hand
|
||||
% Please edit documentation in R/utils.r
|
||||
% Please edit documentation in R/utils.R
|
||||
\name{d2w}
|
||||
\alias{d2w}
|
||||
\title{Convert single digits to words}
|
||||
|
@ -91,7 +91,7 @@ iris |>
|
||||
form.name = sample(c("b", "c"), size = 6, replace = TRUE, prob = rep(.5, 2))
|
||||
) |>
|
||||
purrr::pluck("meta")
|
||||
mtcars |> ds2dd_detailed(add.auto.id = TRUE)
|
||||
mtcars |> numchar2fct() |> ds2dd_detailed(add.auto.id = TRUE)
|
||||
|
||||
## Using column name suffix to carry form name
|
||||
data <- iris |>
|
||||
|
@ -4,7 +4,7 @@
|
||||
\alias{easy_redcap}
|
||||
\title{Secure API key storage and data acquisition in one}
|
||||
\usage{
|
||||
easy_redcap(project.name, widen.data = TRUE, uri, ...)
|
||||
easy_redcap(project.name, widen.data = TRUE, uri, raw_or_label = "both", ...)
|
||||
}
|
||||
\arguments{
|
||||
\item{project.name}{The name of the current project (for key storage with
|
||||
@ -14,6 +14,10 @@ easy_redcap(project.name, widen.data = TRUE, uri, ...)
|
||||
|
||||
\item{uri}{REDCap database API uri}
|
||||
|
||||
\item{raw_or_label}{argument passed on to
|
||||
\link[REDCapCAST]{read_redcap_tables}. Default is "both" to get labelled
|
||||
data.}
|
||||
|
||||
\item{...}{arguments passed on to \link[REDCapCAST]{read_redcap_tables}.}
|
||||
}
|
||||
\value{
|
||||
@ -24,6 +28,6 @@ Secure API key storage and data acquisition in one
|
||||
}
|
||||
\examples{
|
||||
\dontrun{
|
||||
easy_redcap("My_new_project",fields=c("record_id","age","hypertension"))
|
||||
easy_redcap("My_new_project", fields = c("record_id", "age", "hypertension"))
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
% Generated by roxygen2: do not edit by hand
|
||||
% Please edit documentation in R/utils.r
|
||||
% Please edit documentation in R/utils.R
|
||||
\name{focused_metadata}
|
||||
\alias{focused_metadata}
|
||||
\title{focused_metadata}
|
||||
|
@ -1,5 +1,5 @@
|
||||
% Generated by roxygen2: do not edit by hand
|
||||
% Please edit documentation in R/utils.r
|
||||
% Please edit documentation in R/utils.R
|
||||
\name{get_id_name}
|
||||
\alias{get_id_name}
|
||||
\title{Get the id name}
|
||||
|
@ -1,5 +1,5 @@
|
||||
% Generated by roxygen2: do not edit by hand
|
||||
% Please edit documentation in R/utils.r
|
||||
% Please edit documentation in R/utils.R
|
||||
\name{is_repeated_longitudinal}
|
||||
\alias{is_repeated_longitudinal}
|
||||
\title{Test if repeatable or longitudinal}
|
||||
|
@ -1,5 +1,5 @@
|
||||
% Generated by roxygen2: do not edit by hand
|
||||
% Please edit documentation in R/utils.r
|
||||
% Please edit documentation in R/utils.R
|
||||
\name{match_fields_to_form}
|
||||
\alias{match_fields_to_form}
|
||||
\title{Match fields to forms}
|
||||
|
@ -1,5 +1,5 @@
|
||||
% Generated by roxygen2: do not edit by hand
|
||||
% Please edit documentation in R/process_user_input.r
|
||||
% Please edit documentation in R/process_user_input.R
|
||||
\name{process_user_input}
|
||||
\alias{process_user_input}
|
||||
\title{User input processing}
|
||||
|
@ -1,5 +1,5 @@
|
||||
% Generated by roxygen2: do not edit by hand
|
||||
% Please edit documentation in R/process_user_input.r
|
||||
% Please edit documentation in R/process_user_input.R
|
||||
\name{process_user_input.character}
|
||||
\alias{process_user_input.character}
|
||||
\title{User input processing character}
|
||||
|
@ -1,5 +1,5 @@
|
||||
% Generated by roxygen2: do not edit by hand
|
||||
% Please edit documentation in R/process_user_input.r
|
||||
% Please edit documentation in R/process_user_input.R
|
||||
\name{process_user_input.data.frame}
|
||||
\alias{process_user_input.data.frame}
|
||||
\title{User input processing data.frame}
|
||||
|
@ -1,5 +1,5 @@
|
||||
% Generated by roxygen2: do not edit by hand
|
||||
% Please edit documentation in R/process_user_input.r
|
||||
% Please edit documentation in R/process_user_input.R
|
||||
\name{process_user_input.default}
|
||||
\alias{process_user_input.default}
|
||||
\title{User input processing default}
|
||||
|
@ -1,5 +1,5 @@
|
||||
% Generated by roxygen2: do not edit by hand
|
||||
% Please edit documentation in R/process_user_input.r
|
||||
% Please edit documentation in R/process_user_input.R
|
||||
\name{process_user_input.response}
|
||||
\alias{process_user_input.response}
|
||||
\title{User input processing response}
|
||||
|
@ -1,5 +1,5 @@
|
||||
% Generated by roxygen2: do not edit by hand
|
||||
% Please edit documentation in R/utils.r
|
||||
% Please edit documentation in R/utils.R
|
||||
\name{sanitize_split}
|
||||
\alias{sanitize_split}
|
||||
\title{Sanitize list of data frames}
|
||||
|
@ -1,5 +1,5 @@
|
||||
% Generated by roxygen2: do not edit by hand
|
||||
% Please edit documentation in R/utils.r
|
||||
% Please edit documentation in R/utils.R
|
||||
\name{split_non_repeating_forms}
|
||||
\alias{split_non_repeating_forms}
|
||||
\title{Split a data frame into separate tables for each form}
|
||||
|
@ -1,5 +1,5 @@
|
||||
% Generated by roxygen2: do not edit by hand
|
||||
% Please edit documentation in R/utils.r
|
||||
% Please edit documentation in R/utils.R
|
||||
\name{strsplitx}
|
||||
\alias{strsplitx}
|
||||
\title{Extended string splitting}
|
||||
|
@ -37,7 +37,7 @@ shiny_cast()
|
||||
|
||||
To get you started, the easiest way possible, you can use the `easy_redcap()` function (example below).
|
||||
|
||||
You will need an API-key for your REDCap server, the uri/URL/address for the API connection (usually the adress used for accessing your institutions REDCap servar, with an appended "/api/").
|
||||
You will need an API-key for your REDCap server, the uri/URL/address for the API connection (usually the address used for accessing your institutions REDCap server, with an appended "/api/").
|
||||
|
||||
This function includes a few convenience features to ease your further work.
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user