mirror of
https://github.com/agdamsbo/REDCapCAST.git
synced 2024-11-23 13:50:21 +01:00
Compare commits
7 Commits
69e1520aff
...
f094394933
Author | SHA1 | Date | |
---|---|---|---|
f094394933 | |||
a896bf4e76 | |||
47fb3fceca | |||
18544ddcfe | |||
8aa1ec41dc | |||
6fb55fd2cc | |||
c86ae9a364 |
13
DESCRIPTION
13
DESCRIPTION
@ -29,16 +29,11 @@ Suggests:
|
|||||||
Hmisc,
|
Hmisc,
|
||||||
knitr,
|
knitr,
|
||||||
rmarkdown,
|
rmarkdown,
|
||||||
gt,
|
|
||||||
ggplot2,
|
|
||||||
here,
|
|
||||||
styler,
|
styler,
|
||||||
devtools,
|
devtools,
|
||||||
roxygen2,
|
roxygen2,
|
||||||
spelling,
|
spelling,
|
||||||
glue,
|
rhub
|
||||||
rhub,
|
|
||||||
bslib
|
|
||||||
License: GPL (>= 3)
|
License: GPL (>= 3)
|
||||||
Encoding: UTF-8
|
Encoding: UTF-8
|
||||||
LazyData: true
|
LazyData: true
|
||||||
@ -61,7 +56,11 @@ Imports:
|
|||||||
openxlsx2,
|
openxlsx2,
|
||||||
readODS,
|
readODS,
|
||||||
forcats,
|
forcats,
|
||||||
rlang
|
vctrs,
|
||||||
|
gt,
|
||||||
|
bslib,
|
||||||
|
here,
|
||||||
|
glue
|
||||||
Collate:
|
Collate:
|
||||||
'REDCapCAST-package.R'
|
'REDCapCAST-package.R'
|
||||||
'utils.r'
|
'utils.r'
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
# Generated by roxygen2: do not edit by hand
|
# Generated by roxygen2: do not edit by hand
|
||||||
|
|
||||||
S3method(as_factor,character)
|
S3method(as_factor,character)
|
||||||
|
S3method(as_factor,factor)
|
||||||
S3method(as_factor,haven_labelled)
|
S3method(as_factor,haven_labelled)
|
||||||
S3method(as_factor,labelled)
|
S3method(as_factor,labelled)
|
||||||
S3method(as_factor,logical)
|
S3method(as_factor,logical)
|
||||||
@ -12,6 +13,8 @@ S3method(process_user_input,response)
|
|||||||
export(REDCap_split)
|
export(REDCap_split)
|
||||||
export(as_factor)
|
export(as_factor)
|
||||||
export(case_match_regex_list)
|
export(case_match_regex_list)
|
||||||
|
export(cast_data_overview)
|
||||||
|
export(cast_meta_overview)
|
||||||
export(char2choice)
|
export(char2choice)
|
||||||
export(char2cond)
|
export(char2cond)
|
||||||
export(clean_redcap_name)
|
export(clean_redcap_name)
|
||||||
@ -36,6 +39,7 @@ export(html_tag_wrap)
|
|||||||
export(is_repeated_longitudinal)
|
export(is_repeated_longitudinal)
|
||||||
export(match_fields_to_form)
|
export(match_fields_to_form)
|
||||||
export(named_levels)
|
export(named_levels)
|
||||||
|
export(nav_bar_page)
|
||||||
export(numchar2fct)
|
export(numchar2fct)
|
||||||
export(parse_data)
|
export(parse_data)
|
||||||
export(process_user_input)
|
export(process_user_input)
|
||||||
@ -59,6 +63,5 @@ importFrom(keyring,key_set)
|
|||||||
importFrom(openxlsx2,read_xlsx)
|
importFrom(openxlsx2,read_xlsx)
|
||||||
importFrom(purrr,reduce)
|
importFrom(purrr,reduce)
|
||||||
importFrom(readr,parse_time)
|
importFrom(readr,parse_time)
|
||||||
importFrom(rlang,check_dots_used)
|
|
||||||
importFrom(tidyr,pivot_wider)
|
importFrom(tidyr,pivot_wider)
|
||||||
importFrom(tidyselect,all_of)
|
importFrom(tidyselect,all_of)
|
||||||
|
231
R/as_factor.R
231
R/as_factor.R
@ -5,87 +5,173 @@
|
|||||||
#' ta loss in case of rich formatted and labelled data.
|
#' ta loss in case of rich formatted and labelled data.
|
||||||
#'
|
#'
|
||||||
#' Please refer to parent functions for extended documentation.
|
#' Please refer to parent functions for extended documentation.
|
||||||
|
#' To avoid redundancy calls and errors, functions are copy-pasted here
|
||||||
#'
|
#'
|
||||||
#' @param x Object to coerce to a factor.
|
#' @param x Object to coerce to a factor.
|
||||||
#' @param ... Other arguments passed down to method.
|
#' @param ... Other arguments passed down to method.
|
||||||
#' @export
|
#' @export
|
||||||
#' @examples
|
#' @examples
|
||||||
#' # will preserve all attributes but class
|
#' # will preserve all attributes
|
||||||
#' c(1, 4, 3, "A", 7, 8, 1) |> as_factor()
|
#' c(1, 4, 3, "A", 7, 8, 1) |> as_factor()
|
||||||
#' structure(c(1, 2, 3, 2, 10, 9),
|
#' structure(c(1, 2, 3, 2, 10, 9),
|
||||||
#' labels = c(Unknown = 9, Refused = 10)
|
#' labels = c(Unknown = 9, Refused = 10)
|
||||||
#' ) |>
|
#' ) |>
|
||||||
#' as_factor()
|
#' as_factor() |> dput()
|
||||||
#'
|
#'
|
||||||
#' structure(c(1, 2, 3, 2, 10, 9),
|
#' structure(c(1, 2, 3, 2, 10, 9),
|
||||||
#' labels = c(Unknown = 9, Refused = 10),
|
#' labels = c(Unknown = 9, Refused = 10),
|
||||||
#' class = "haven_labelled"
|
#' class = "haven_labelled"
|
||||||
#' ) |>
|
#' ) |>
|
||||||
#' as_factor()
|
#' as_factor()
|
||||||
#'
|
|
||||||
#' @importFrom forcats as_factor
|
#' @importFrom forcats as_factor
|
||||||
#' @importFrom rlang check_dots_used
|
|
||||||
#' @export
|
#' @export
|
||||||
#' @name as_factor
|
#' @name as_factor
|
||||||
as_factor <- function(x, ...) {
|
as_factor <- function(x, ...) {
|
||||||
rlang::check_dots_used()
|
|
||||||
UseMethod("as_factor")
|
UseMethod("as_factor")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#' @rdname as_factor
|
||||||
|
#' @export
|
||||||
|
as_factor.factor <- function(x, ...) {
|
||||||
|
x
|
||||||
|
}
|
||||||
|
|
||||||
#' @rdname as_factor
|
#' @rdname as_factor
|
||||||
#' @export
|
#' @export
|
||||||
as_factor.logical <- function(x, ...) {
|
as_factor.logical <- function(x, ...) {
|
||||||
labels <- get_attr(x)
|
labels <- get_attr(x)
|
||||||
x <- forcats::as_factor(x, ...)
|
x <- factor(x, levels = c("FALSE", "TRUE"))
|
||||||
set_attr(x, labels[-match("class", names(labels))])
|
set_attr(x, labels, overwrite = FALSE)
|
||||||
}
|
}
|
||||||
|
|
||||||
#' @rdname as_factor
|
#' @rdname as_factor
|
||||||
#' @export
|
#' @export
|
||||||
as_factor.numeric <- function(x, ...) {
|
as_factor.numeric <- function(x, ...) {
|
||||||
labels <- get_attr(x)
|
labels <- get_attr(x)
|
||||||
x <- forcats::as_factor(x, ...)
|
x <- factor(x)
|
||||||
set_attr(x, labels[-match("class", names(labels))])
|
set_attr(x, labels, overwrite = FALSE)
|
||||||
}
|
}
|
||||||
|
|
||||||
#' @rdname as_factor
|
#' @rdname as_factor
|
||||||
#' @export
|
#' @export
|
||||||
as_factor.character <- function(x, ...) {
|
as_factor.character <- function(x, ...) {
|
||||||
labels <- get_attr(x)
|
labels <- get_attr(x)
|
||||||
x <- forcats::as_factor(x, ...)
|
if (is.roman(x)){
|
||||||
set_attr(x, labels[-match("class", names(labels))])
|
x <- factor(x)
|
||||||
|
} else {
|
||||||
|
x <- structure(
|
||||||
|
forcats::fct_inorder(x),
|
||||||
|
label = attr(x, "label", exact = TRUE)
|
||||||
|
)}
|
||||||
|
set_attr(x, labels, overwrite = FALSE)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#' @param ordered If `TRUE` create an ordered (ordinal) factor, if
|
||||||
|
#' `FALSE` (the default) create a regular (nominal) factor.
|
||||||
|
#' @param levels How to create the levels of the generated factor:
|
||||||
|
#'
|
||||||
|
#' * "default": uses labels where available, otherwise the values.
|
||||||
|
#' Labels are sorted by value.
|
||||||
|
#' * "both": like "default", but pastes together the level and value
|
||||||
|
#' * "label": use only the labels; unlabelled values become `NA`
|
||||||
|
#' * "values": use only the values
|
||||||
#' @rdname as_factor
|
#' @rdname as_factor
|
||||||
#' @export
|
#' @export
|
||||||
as_factor.haven_labelled <- function(x, ...) {
|
as_factor.haven_labelled <- function(x, levels = c("default", "labels", "values", "both"),
|
||||||
labels <- get_attr(x)
|
ordered = FALSE, ...) {
|
||||||
x <- haven::as_factor(x, ...)
|
labels_all <- get_attr(x)
|
||||||
set_attr(x, labels[-match("class", names(labels))])
|
|
||||||
|
levels <- match.arg(levels)
|
||||||
|
label <- attr(x, "label", exact = TRUE)
|
||||||
|
labels <- attr(x, "labels")
|
||||||
|
|
||||||
|
if (levels %in% c("default", "both")) {
|
||||||
|
if (levels == "both") {
|
||||||
|
names(labels) <- paste0("[", labels, "] ", names(labels))
|
||||||
|
}
|
||||||
|
|
||||||
|
# Replace each value with its label
|
||||||
|
vals <- unique(vctrs::vec_data(x))
|
||||||
|
levs <- replace_with(vals, unname(labels), names(labels))
|
||||||
|
# Ensure all labels are preserved
|
||||||
|
levs <- sort(c(stats::setNames(vals, levs), labels), na.last = TRUE)
|
||||||
|
levs <- unique(names(levs))
|
||||||
|
|
||||||
|
x <- replace_with(vctrs::vec_data(x), unname(labels), names(labels))
|
||||||
|
|
||||||
|
x <- factor(x, levels = levs, ordered = ordered)
|
||||||
|
} else if (levels == "labels") {
|
||||||
|
levs <- unname(labels)
|
||||||
|
labs <- names(labels)
|
||||||
|
x <- replace_with(vctrs::vec_data(x), levs, labs)
|
||||||
|
x <- factor(x, unique(labs), ordered = ordered)
|
||||||
|
} else if (levels == "values") {
|
||||||
|
if (all(x %in% labels)) {
|
||||||
|
levels <- unname(labels)
|
||||||
|
} else {
|
||||||
|
levels <- sort(unique(vctrs::vec_data(x)))
|
||||||
|
}
|
||||||
|
x <- factor(vctrs::vec_data(x), levels, ordered = ordered)
|
||||||
|
}
|
||||||
|
|
||||||
|
x <- structure(x, label = label)
|
||||||
|
|
||||||
|
set_attr(x, labels_all, overwrite = FALSE)
|
||||||
}
|
}
|
||||||
|
|
||||||
#' @export
|
#' @export
|
||||||
#' @rdname as_factor
|
#' @rdname as_factor
|
||||||
as_factor.labelled <- as_factor.haven_labelled
|
as_factor.labelled <- as_factor.haven_labelled
|
||||||
|
|
||||||
|
replace_with <- function(x, from, to) {
|
||||||
|
stopifnot(length(from) == length(to))
|
||||||
|
|
||||||
|
out <- x
|
||||||
|
# First replace regular values
|
||||||
|
matches <- match(x, from, incomparables = NA)
|
||||||
|
if (anyNA(matches)) {
|
||||||
|
out[!is.na(matches)] <- to[matches[!is.na(matches)]]
|
||||||
|
} else {
|
||||||
|
out <- to[matches]
|
||||||
|
}
|
||||||
|
|
||||||
|
# Then tagged missing values
|
||||||
|
tagged <- haven::is_tagged_na(x)
|
||||||
|
if (!any(tagged)) {
|
||||||
|
return(out)
|
||||||
|
}
|
||||||
|
|
||||||
|
matches <- match(haven::na_tag(x), haven::na_tag(from), incomparables = NA)
|
||||||
|
|
||||||
|
# Could possibly be faster to use anyNA(matches)
|
||||||
|
out[!is.na(matches)] <- to[matches[!is.na(matches)]]
|
||||||
|
out
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#' Get named vector of factor levels and values
|
#' Get named vector of factor levels and values
|
||||||
#'
|
#'
|
||||||
#' @param data factor
|
#' @param data factor
|
||||||
#' @param label character string of attribute with named vector of factor labels
|
#' @param label character string of attribute with named vector of factor labels
|
||||||
|
#' @param na.label character string to refactor NA values. Default is NULL.
|
||||||
|
#' @param na.value new value for NA strings. Ignored if na.label is NULL.
|
||||||
|
#' Default is 99.
|
||||||
#'
|
#'
|
||||||
#' @return named vector
|
#' @return named vector
|
||||||
#' @export
|
#' @export
|
||||||
#'
|
#'
|
||||||
#' @examples
|
#' @examples
|
||||||
|
#' \dontrun{
|
||||||
#' structure(c(1, 2, 3, 2, 10, 9),
|
#' structure(c(1, 2, 3, 2, 10, 9),
|
||||||
#' labels = c(Unknown = 9, Refused = 10),
|
#' labels = c(Unknown = 9, Refused = 10),
|
||||||
#' class = "haven_labelled"
|
#' class = "haven_labelled"
|
||||||
#' ) |> as_factor() |> named_levels()
|
#' ) |>
|
||||||
named_levels <- function(data, label = "labels",na.label=NULL, na.value=99) {
|
#' as_factor() |>
|
||||||
|
#' named_levels()
|
||||||
|
#' }
|
||||||
|
named_levels <- function(data, label = "labels", na.label = NULL, na.value = 99) {
|
||||||
stopifnot(is.factor(data))
|
stopifnot(is.factor(data))
|
||||||
if (!is.null(na.label)){
|
if (!is.null(na.label)) {
|
||||||
attrs <- attributes(data)
|
attrs <- attributes(data)
|
||||||
lvls <- as.character(data)
|
lvls <- as.character(data)
|
||||||
lvls[is.na(lvls)] <- na.label
|
lvls[is.na(lvls)] <- na.label
|
||||||
@ -95,17 +181,24 @@ named_levels <- function(data, label = "labels",na.label=NULL, na.value=99) {
|
|||||||
lbls <- data.frame(
|
lbls <- data.frame(
|
||||||
name = lvls,
|
name = lvls,
|
||||||
value = vals
|
value = vals
|
||||||
) |> unique() |>
|
) |>
|
||||||
|
unique() |>
|
||||||
(\(d){
|
(\(d){
|
||||||
stats::setNames(d$value, d$name)
|
stats::setNames(d$value, d$name)
|
||||||
})() |>
|
})() |>
|
||||||
sort()
|
sort()
|
||||||
|
|
||||||
data <- do.call(structure,
|
data <- do.call(
|
||||||
c(list(.Data=match(vals,lbls)),
|
structure,
|
||||||
attrs[-match("levels", names(attrs))],
|
c(
|
||||||
list(levels=names(lbls),
|
list(.Data = match(vals, lbls)),
|
||||||
labels=lbls)))
|
attrs[-match("levels", names(attrs))],
|
||||||
|
list(
|
||||||
|
levels = names(lbls),
|
||||||
|
labels = lbls
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
d <- data.frame(
|
d <- data.frame(
|
||||||
@ -117,21 +210,27 @@ named_levels <- function(data, label = "labels",na.label=NULL, na.value=99) {
|
|||||||
## Applying labels
|
## Applying labels
|
||||||
attr_l <- attr(x = data, which = label, exact = TRUE)
|
attr_l <- attr(x = data, which = label, exact = TRUE)
|
||||||
if (length(attr_l) != 0) {
|
if (length(attr_l) != 0) {
|
||||||
d$value[match(names(attr_l), d$name)] <- unname(attr_l)
|
if (all(names(attr_l) %in% d$name)){
|
||||||
|
d$value[match(names(attr_l), d$name)] <- unname(attr_l)
|
||||||
|
}else {
|
||||||
|
d$name[match(attr_l, d$name)] <- names(attr_l)
|
||||||
|
d$value[match(names(attr_l), d$name)] <- unname(attr_l)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
out <- stats::setNames(d$value, d$name)
|
out <- stats::setNames(d$value, d$name)
|
||||||
## Sort if levels are numeric
|
## Sort if levels are numeric
|
||||||
## Else, they appear in order of appearance
|
## Else, they appear in order of appearance
|
||||||
if (identical(
|
if (possibly_numeric(levels(data))) {
|
||||||
levels(data),
|
|
||||||
suppressWarnings(as.character(as.numeric(levels(data))))
|
|
||||||
)) {
|
|
||||||
out <- out |> sort()
|
out <- out |> sort()
|
||||||
}
|
}
|
||||||
out
|
out
|
||||||
}
|
}
|
||||||
|
|
||||||
|
is.roman <- function(data){
|
||||||
|
identical(data,as.character(utils::as.roman(data)))
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#' Allows conversion of factor to numeric values preserving original levels
|
#' Allows conversion of factor to numeric values preserving original levels
|
||||||
#'
|
#'
|
||||||
@ -142,7 +241,8 @@ named_levels <- function(data, label = "labels",na.label=NULL, na.value=99) {
|
|||||||
#'
|
#'
|
||||||
#' @examples
|
#' @examples
|
||||||
#' c(1, 4, 3, "A", 7, 8, 1) |>
|
#' c(1, 4, 3, "A", 7, 8, 1) |>
|
||||||
#' as_factor() |> fct2num()
|
#' as_factor() |>
|
||||||
|
#' fct2num()
|
||||||
#'
|
#'
|
||||||
#' structure(c(1, 2, 3, 2, 10, 9),
|
#' structure(c(1, 2, 3, 2, 10, 9),
|
||||||
#' labels = c(Unknown = 9, Refused = 10),
|
#' labels = c(Unknown = 9, Refused = 10),
|
||||||
@ -152,13 +252,44 @@ named_levels <- function(data, label = "labels",na.label=NULL, na.value=99) {
|
|||||||
#' fct2num()
|
#' fct2num()
|
||||||
#'
|
#'
|
||||||
#' structure(c(1, 2, 3, 2, 10, 9),
|
#' structure(c(1, 2, 3, 2, 10, 9),
|
||||||
#' labels = c(Unknown = 9, Refused = 10)
|
#' labels = c(Unknown = 9, Refused = 10),
|
||||||
|
#' class = "labelled"
|
||||||
#' ) |>
|
#' ) |>
|
||||||
#' as_factor() |>
|
#' as_factor() |>
|
||||||
#' fct2num()
|
#' fct2num()
|
||||||
|
#'
|
||||||
|
#' # Outlier with labels, but no class of origin, handled like numeric vector
|
||||||
|
#' # structure(c(1, 2, 3, 2, 10, 9),
|
||||||
|
#' # labels = c(Unknown = 9, Refused = 10)
|
||||||
|
#' # ) |>
|
||||||
|
#' # as_factor() |>
|
||||||
|
#' # fct2num()
|
||||||
|
#'
|
||||||
|
#' v <- sample(6:19,20,TRUE) |> factor()
|
||||||
|
#' dput(v)
|
||||||
|
#' named_levels(v)
|
||||||
|
#' fct2num(v)
|
||||||
fct2num <- function(data) {
|
fct2num <- function(data) {
|
||||||
stopifnot(is.factor(data))
|
stopifnot(is.factor(data))
|
||||||
as.numeric(named_levels(data))[match(data, names(named_levels(data)))]
|
if (is.character(named_levels(data))){
|
||||||
|
values <- as.numeric(named_levels(data))
|
||||||
|
} else {
|
||||||
|
values <- named_levels(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
out <- values[match(data, names(named_levels(data)))]
|
||||||
|
|
||||||
|
## If no NA on numeric coercion, of original names, then return
|
||||||
|
## original numeric names, else values
|
||||||
|
if (possibly_numeric(out)) {
|
||||||
|
out <- as.numeric(names(out))
|
||||||
|
}
|
||||||
|
unname(out)
|
||||||
|
}
|
||||||
|
|
||||||
|
possibly_numeric <- function(data){
|
||||||
|
length(stats::na.omit(suppressWarnings(as.numeric(names(data))))) ==
|
||||||
|
length(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
#' Extract attribute. Returns NA if none
|
#' Extract attribute. Returns NA if none
|
||||||
@ -171,11 +302,12 @@ fct2num <- function(data) {
|
|||||||
#'
|
#'
|
||||||
#' @examples
|
#' @examples
|
||||||
#' attr(mtcars$mpg, "label") <- "testing"
|
#' attr(mtcars$mpg, "label") <- "testing"
|
||||||
#' sapply(mtcars, get_attr)
|
#' do.call(c, sapply(mtcars, get_attr))
|
||||||
#' lapply(mtcars, \(.x)get_attr(.x, NULL))
|
#' \dontrun{
|
||||||
#' mtcars |>
|
#' mtcars |>
|
||||||
#' numchar2fct(numeric.threshold = 6) |>
|
#' numchar2fct(numeric.threshold = 6) |>
|
||||||
#' ds2dd_detailed()
|
#' ds2dd_detailed()
|
||||||
|
#' }
|
||||||
get_attr <- function(data, attr = NULL) {
|
get_attr <- function(data, attr = NULL) {
|
||||||
if (is.null(attr)) {
|
if (is.null(attr)) {
|
||||||
attributes(data)
|
attributes(data)
|
||||||
@ -195,17 +327,27 @@ get_attr <- function(data, attr = NULL) {
|
|||||||
#' @param data vector
|
#' @param data vector
|
||||||
#' @param label label
|
#' @param label label
|
||||||
#' @param attr attribute name
|
#' @param attr attribute name
|
||||||
|
#' @param overwrite overwrite existing attributes. Default is FALSE.
|
||||||
#'
|
#'
|
||||||
#' @return vector with attribute
|
#' @return vector with attribute
|
||||||
#' @export
|
#' @export
|
||||||
#'
|
#'
|
||||||
set_attr <- function(data, label, attr = NULL) {
|
set_attr <- function(data, label, attr = NULL, overwrite = FALSE) {
|
||||||
|
# browser()
|
||||||
if (is.null(attr)) {
|
if (is.null(attr)) {
|
||||||
## Has to be list...
|
## Has to be a named list
|
||||||
stopifnot(is.list(label))
|
## Will not fail, but just return original data
|
||||||
## ... with names
|
if (!is.list(label) | length(label) != length(names(label))) {
|
||||||
stopifnot(length(label)==length(names(label)))
|
return(data)
|
||||||
attributes(data) <- c(attributes(data),label)
|
}
|
||||||
|
## Only include named labels
|
||||||
|
label <- label[!is.na(names(label))]
|
||||||
|
|
||||||
|
if (!overwrite) {
|
||||||
|
label <- label[!names(label) %in% names(attributes(data))]
|
||||||
|
}
|
||||||
|
attributes(data) <- c(attributes(data), label)
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
attr(data, attr) <- label
|
attr(data, attr) <- label
|
||||||
}
|
}
|
||||||
@ -238,12 +380,3 @@ haven_all_levels <- function(data) {
|
|||||||
}
|
}
|
||||||
out
|
out
|
||||||
}
|
}
|
||||||
|
|
||||||
# readr::read_rds("/Users/au301842/PAaSO/labelled_test.rds") |> ds2dd_detailed()
|
|
||||||
#' sample(c(TRUE,FALSE,NA),20,TRUE) |> set_attr("hidden","status") |> trial_fct() |> named_levels(na.label = "Missing") |> sort()
|
|
||||||
# trial_fct <- function(x){
|
|
||||||
# labels <- get_attr(x)
|
|
||||||
# x <- factor(x, levels = c("FALSE", "TRUE"))
|
|
||||||
# set_attr(x, labels[-match("class", names(labels))])
|
|
||||||
# }
|
|
||||||
|
|
||||||
|
@ -141,6 +141,7 @@ hms2character <- function(data) {
|
|||||||
#' @export
|
#' @export
|
||||||
#'
|
#'
|
||||||
#' @examples
|
#' @examples
|
||||||
|
#' \dontrun{
|
||||||
#' data <- REDCapCAST::redcapcast_data
|
#' data <- REDCapCAST::redcapcast_data
|
||||||
#' data |> ds2dd_detailed()
|
#' data |> ds2dd_detailed()
|
||||||
#' iris |> ds2dd_detailed(add.auto.id = TRUE)
|
#' iris |> ds2dd_detailed(add.auto.id = TRUE)
|
||||||
@ -157,6 +158,7 @@ hms2character <- function(data) {
|
|||||||
#' names(data) <- glue::glue("{sample(x = c('a','b'),size = length(names(data)),
|
#' names(data) <- glue::glue("{sample(x = c('a','b'),size = length(names(data)),
|
||||||
#' replace=TRUE,prob = rep(x=.5,2))}__{names(data)}")
|
#' replace=TRUE,prob = rep(x=.5,2))}__{names(data)}")
|
||||||
#' data |> ds2dd_detailed(form.sep = "__")
|
#' data |> ds2dd_detailed(form.sep = "__")
|
||||||
|
#' }
|
||||||
ds2dd_detailed <- function(data,
|
ds2dd_detailed <- function(data,
|
||||||
add.auto.id = FALSE,
|
add.auto.id = FALSE,
|
||||||
date.format = "dmy",
|
date.format = "dmy",
|
||||||
@ -195,6 +197,8 @@ ds2dd_detailed <- function(data,
|
|||||||
record_id = seq_len(nrow(data)),
|
record_id = seq_len(nrow(data)),
|
||||||
data
|
data
|
||||||
)
|
)
|
||||||
|
# set_attr(data$record_id,label="ID",attr="label")
|
||||||
|
|
||||||
message("A default id column has been added")
|
message("A default id column has been added")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -335,12 +339,15 @@ ds2dd_detailed <- function(data,
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
list(
|
out <- list(
|
||||||
data = data |>
|
data = data |>
|
||||||
hms2character() |>
|
hms2character() |>
|
||||||
stats::setNames(dd$field_name),
|
stats::setNames(dd$field_name),
|
||||||
meta = dd
|
meta = dd
|
||||||
)
|
)
|
||||||
|
|
||||||
|
class(out) <- c("REDCapCAST",class(out))
|
||||||
|
out
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -416,9 +423,11 @@ mark_complete <- function(upload, ls) {
|
|||||||
#' @export
|
#' @export
|
||||||
#'
|
#'
|
||||||
#' @examples
|
#' @examples
|
||||||
|
#' \dontrun{
|
||||||
#' mtcars |>
|
#' mtcars |>
|
||||||
#' parse_data() |>
|
#' parse_data() |>
|
||||||
#' str()
|
#' str()
|
||||||
|
#' }
|
||||||
parse_data <- function(data,
|
parse_data <- function(data,
|
||||||
guess_type = TRUE,
|
guess_type = TRUE,
|
||||||
col_types = NULL,
|
col_types = NULL,
|
||||||
@ -434,7 +443,7 @@ parse_data <- function(data,
|
|||||||
## Parses haven data by applying labels as factors in case of any
|
## Parses haven data by applying labels as factors in case of any
|
||||||
if (do.call(c, lapply(data, (\(x)inherits(x, "haven_labelled")))) |> any()) {
|
if (do.call(c, lapply(data, (\(x)inherits(x, "haven_labelled")))) |> any()) {
|
||||||
data <- data |>
|
data <- data |>
|
||||||
haven::as_factor()
|
as_factor()
|
||||||
}
|
}
|
||||||
|
|
||||||
## Applying readr cols
|
## Applying readr cols
|
||||||
@ -474,6 +483,7 @@ parse_data <- function(data,
|
|||||||
#' @importFrom forcats as_factor
|
#' @importFrom forcats as_factor
|
||||||
#'
|
#'
|
||||||
#' @examples
|
#' @examples
|
||||||
|
#' \dontrun{
|
||||||
#' sample(seq_len(4), 20, TRUE) |>
|
#' sample(seq_len(4), 20, TRUE) |>
|
||||||
#' var2fct(6) |>
|
#' var2fct(6) |>
|
||||||
#' summary()
|
#' summary()
|
||||||
@ -481,9 +491,10 @@ parse_data <- function(data,
|
|||||||
#' var2fct(6) |>
|
#' var2fct(6) |>
|
||||||
#' summary()
|
#' summary()
|
||||||
#' sample(letters[1:4], 20, TRUE) |> var2fct(6)
|
#' sample(letters[1:4], 20, TRUE) |> var2fct(6)
|
||||||
|
#' }
|
||||||
var2fct <- function(data, unique.n) {
|
var2fct <- function(data, unique.n) {
|
||||||
if (length(unique(data)) <= unique.n) {
|
if (length(unique(data)) <= unique.n) {
|
||||||
forcats::as_factor(data)
|
as_factor(data)
|
||||||
} else {
|
} else {
|
||||||
data
|
data
|
||||||
}
|
}
|
||||||
@ -505,9 +516,11 @@ var2fct <- function(data, unique.n) {
|
|||||||
#'
|
#'
|
||||||
#' @examples
|
#' @examples
|
||||||
#' mtcars |> str()
|
#' mtcars |> str()
|
||||||
|
#' \dontrun{
|
||||||
#' mtcars |>
|
#' mtcars |>
|
||||||
#' numchar2fct(numeric.threshold = 6) |>
|
#' numchar2fct(numeric.threshold = 6) |>
|
||||||
#' str()
|
#' str()
|
||||||
|
#' }
|
||||||
numchar2fct <- function(data, numeric.threshold = 6, character.throshold = 6) {
|
numchar2fct <- function(data, numeric.threshold = 6, character.throshold = 6) {
|
||||||
data |>
|
data |>
|
||||||
dplyr::mutate(
|
dplyr::mutate(
|
||||||
|
213
R/shiny_cast.R
213
R/shiny_cast.R
@ -78,3 +78,216 @@ read_input <- function(file, consider.na = c("NA", '""', "")) {
|
|||||||
|
|
||||||
df
|
df
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#' Overview of REDCapCAST data for shiny
|
||||||
|
#'
|
||||||
|
#' @param data list with class 'REDCapCAST'
|
||||||
|
#'
|
||||||
|
#' @return gt object
|
||||||
|
#' @export
|
||||||
|
cast_data_overview <- function(data){
|
||||||
|
stopifnot("REDCapCAST" %in% class(data))
|
||||||
|
data |>
|
||||||
|
purrr::pluck("data") |>
|
||||||
|
utils::head(20) |>
|
||||||
|
# dplyr::tibble() |>
|
||||||
|
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."
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#' Overview of REDCapCAST meta data for shiny
|
||||||
|
#'
|
||||||
|
#' @param data list with class 'REDCapCAST'
|
||||||
|
#'
|
||||||
|
#' @return gt object
|
||||||
|
#' @export
|
||||||
|
cast_meta_overview <- function(data){
|
||||||
|
stopifnot("REDCapCAST" %in% class(data))
|
||||||
|
data |>
|
||||||
|
purrr::pluck("meta") |>
|
||||||
|
# dplyr::tibble() |>
|
||||||
|
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()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#' Nav_bar defining function for shiny ui
|
||||||
|
#'
|
||||||
|
#' @return shiny object
|
||||||
|
#' @export
|
||||||
|
#'
|
||||||
|
nav_bar_page <- function(){
|
||||||
|
bslib::page_navbar(
|
||||||
|
title = "Easy REDCap database creation",
|
||||||
|
sidebar = bslib::sidebar(
|
||||||
|
width = 300,
|
||||||
|
shiny::h5("Metadata casting"),
|
||||||
|
shiny::fileInput(
|
||||||
|
inputId = "ds",
|
||||||
|
label = "Upload spreadsheet",
|
||||||
|
multiple = FALSE,
|
||||||
|
accept = c(
|
||||||
|
".csv",
|
||||||
|
".xls",
|
||||||
|
".xlsx",
|
||||||
|
".dta",
|
||||||
|
".rds",
|
||||||
|
".ods"
|
||||||
|
)
|
||||||
|
),
|
||||||
|
# shiny::actionButton(
|
||||||
|
# inputId = "load_data",
|
||||||
|
# label = "Load data",
|
||||||
|
# icon = shiny::icon("circle-down")
|
||||||
|
# ),
|
||||||
|
shiny::helpText("Have a look at the preview panels to validate the data dictionary and imported data."),
|
||||||
|
# For some odd reason this only unfolds when the preview panel is shown..
|
||||||
|
# This has been solved by adding an arbitrary button to load data - which was abandoned again
|
||||||
|
shiny::conditionalPanel(
|
||||||
|
condition = "output.uploaded=='yes'",
|
||||||
|
shiny::radioButtons(
|
||||||
|
inputId = "add_id",
|
||||||
|
label = "Add ID, or use first column?",
|
||||||
|
selected = "no",
|
||||||
|
inline = TRUE,
|
||||||
|
choices = list(
|
||||||
|
"First column" = "no",
|
||||||
|
"Add ID" = "yes",
|
||||||
|
"No ID" = "none"
|
||||||
|
)
|
||||||
|
),
|
||||||
|
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'",
|
||||||
|
shiny::uiOutput("factor_vars")
|
||||||
|
),
|
||||||
|
# condition = "input.load_data",
|
||||||
|
# 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."),
|
||||||
|
# Button
|
||||||
|
shiny::downloadButton(outputId = "downloadData", label = "Download renamed data"),
|
||||||
|
|
||||||
|
# Button
|
||||||
|
shiny::downloadButton(outputId = "downloadMeta", label = "Download data dictionary"),
|
||||||
|
|
||||||
|
# Button
|
||||||
|
shiny::downloadButton(outputId = "downloadInstrument", label = "Download as instrument"),
|
||||||
|
|
||||||
|
# Horizontal line ----
|
||||||
|
shiny::tags$hr(),
|
||||||
|
shiny::radioButtons(
|
||||||
|
inputId = "upload_redcap",
|
||||||
|
label = "Upload directly to REDCap server?",
|
||||||
|
selected = "no",
|
||||||
|
inline = TRUE,
|
||||||
|
choices = list(
|
||||||
|
"No" = "no",
|
||||||
|
"Yes" = "yes"
|
||||||
|
)
|
||||||
|
),
|
||||||
|
shiny::conditionalPanel(
|
||||||
|
condition = "input.upload_redcap=='yes'",
|
||||||
|
shiny::h4("2) Data base upload"),
|
||||||
|
shiny::helpText("This tool is usable for now. Detailed instructions are coming."),
|
||||||
|
shiny::textInput(
|
||||||
|
inputId = "uri",
|
||||||
|
label = "URI",
|
||||||
|
value = "https://redcap.your.institution/api/"
|
||||||
|
),
|
||||||
|
shiny::textInput(
|
||||||
|
inputId = "api",
|
||||||
|
label = "API key",
|
||||||
|
value = ""
|
||||||
|
),
|
||||||
|
shiny::helpText("An API key is an access key to the REDCap database. Please", shiny::a("see here for directions", href = "https://www.iths.org/news/redcap-tip/redcap-api-101/"), " to obtain an API key for your project."),
|
||||||
|
shiny::actionButton(
|
||||||
|
inputId = "upload.meta",
|
||||||
|
label = "Upload datadictionary", icon = shiny::icon("book-bookmark")
|
||||||
|
),
|
||||||
|
shiny::helpText("Please note, that before uploading any real data, put your project
|
||||||
|
into production mode."),
|
||||||
|
shiny::actionButton(
|
||||||
|
inputId = "upload.data",
|
||||||
|
label = "Upload data", icon = shiny::icon("upload")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
shiny::br(),
|
||||||
|
shiny::br(),
|
||||||
|
shiny::br(),
|
||||||
|
shiny::p(
|
||||||
|
"License: ", shiny::a("GPL-3+", href = "https://agdamsbo.github.io/REDCapCAST/LICENSE.html")
|
||||||
|
),
|
||||||
|
shiny::p(
|
||||||
|
shiny::a("Package documentation", href = "https://agdamsbo.github.io/REDCapCAST")
|
||||||
|
)
|
||||||
|
),
|
||||||
|
bslib::nav_panel(
|
||||||
|
title = "Intro",
|
||||||
|
shiny::markdown(readLines("www/SHINYCAST.md")),
|
||||||
|
shiny::br()
|
||||||
|
),
|
||||||
|
# bslib::nav_spacer(),
|
||||||
|
bslib::nav_panel(
|
||||||
|
title = "Data preview",
|
||||||
|
gt::gt_output(outputId = "data.tbl")
|
||||||
|
# shiny::htmlOutput(outputId = "data.tbl", container = shiny::span)
|
||||||
|
),
|
||||||
|
bslib::nav_panel(
|
||||||
|
title = "Dictionary overview",
|
||||||
|
gt::gt_output(outputId = "meta.tbl")
|
||||||
|
# shiny::htmlOutput(outputId = "meta.tbl", container = shiny::span)
|
||||||
|
),
|
||||||
|
bslib::nav_panel(
|
||||||
|
title = "Upload",
|
||||||
|
shiny::h3("Meta upload overview"),
|
||||||
|
shiny::textOutput(outputId = "upload.meta.print"),
|
||||||
|
shiny::h3("Data upload overview"),
|
||||||
|
shiny::textOutput(outputId = "upload.data.print")
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
@ -5,6 +5,6 @@ account: agdamsbo
|
|||||||
server: shinyapps.io
|
server: shinyapps.io
|
||||||
hostUrl: https://api.shinyapps.io/v1
|
hostUrl: https://api.shinyapps.io/v1
|
||||||
appId: 11351429
|
appId: 11351429
|
||||||
bundleId:
|
bundleId: 9392320
|
||||||
url: https://agdamsbo.shinyapps.io/redcapcast/
|
url: https://agdamsbo.shinyapps.io/redcapcast/
|
||||||
version: 1
|
version: 1
|
||||||
|
@ -5,7 +5,6 @@ library(haven)
|
|||||||
library(readODS)
|
library(readODS)
|
||||||
library(readr)
|
library(readr)
|
||||||
library(dplyr)
|
library(dplyr)
|
||||||
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")
|
||||||
@ -103,53 +102,12 @@ server <- function(input, output, session) {
|
|||||||
|
|
||||||
output$data.tbl <- gt::render_gt(
|
output$data.tbl <- gt::render_gt(
|
||||||
dd() |>
|
dd() |>
|
||||||
purrr::pluck("data") |>
|
cast_data_overview()
|
||||||
head(20) |>
|
|
||||||
# dplyr::tibble() |>
|
|
||||||
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") |>
|
cast_meta_overview()
|
||||||
# dplyr::tibble() |>
|
|
||||||
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 ----
|
||||||
|
@ -2,143 +2,6 @@ ui <-
|
|||||||
bslib::page(
|
bslib::page(
|
||||||
theme = bslib::bs_theme(preset = "united"),
|
theme = bslib::bs_theme(preset = "united"),
|
||||||
title = "REDCap database creator",
|
title = "REDCap database creator",
|
||||||
bslib::page_navbar(
|
nav_bar_page()
|
||||||
title = "Easy REDCap database creation",
|
|
||||||
sidebar = bslib::sidebar(
|
|
||||||
width = 300,
|
|
||||||
shiny::h5("Metadata casting"),
|
|
||||||
shiny::fileInput(
|
|
||||||
inputId = "ds",
|
|
||||||
label = "Upload spreadsheet",
|
|
||||||
multiple = FALSE,
|
|
||||||
accept = c(
|
|
||||||
".csv",
|
|
||||||
".xls",
|
|
||||||
".xlsx",
|
|
||||||
".dta",
|
|
||||||
".rds",
|
|
||||||
".ods"
|
|
||||||
)
|
|
||||||
),
|
|
||||||
# shiny::actionButton(
|
|
||||||
# inputId = "load_data",
|
|
||||||
# label = "Load data",
|
|
||||||
# icon = shiny::icon("circle-down")
|
|
||||||
# ),
|
|
||||||
shiny::helpText("Have a look at the preview panels to validate the data dictionary and imported data."),
|
|
||||||
# For some odd reason this only unfolds when the preview panel is shown..
|
|
||||||
# This has been solved by adding an arbitrary button to load data - which was abandoned again
|
|
||||||
shiny::conditionalPanel(
|
|
||||||
condition = "output.uploaded=='yes'",
|
|
||||||
shiny::radioButtons(
|
|
||||||
inputId = "add_id",
|
|
||||||
label = "Add ID, or use first column?",
|
|
||||||
selected = "no",
|
|
||||||
inline = TRUE,
|
|
||||||
choices = list(
|
|
||||||
"First column" = "no",
|
|
||||||
"Add ID" = "yes",
|
|
||||||
"No ID" = "none"
|
|
||||||
)
|
|
||||||
),
|
|
||||||
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",
|
|
||||||
# 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."),
|
|
||||||
# Button
|
|
||||||
shiny::downloadButton(outputId = "downloadData", label = "Download renamed data"),
|
|
||||||
|
|
||||||
# Button
|
|
||||||
shiny::downloadButton(outputId = "downloadMeta", label = "Download data dictionary"),
|
|
||||||
|
|
||||||
# Button
|
|
||||||
shiny::downloadButton(outputId = "downloadInstrument", label = "Download as instrument"),
|
|
||||||
|
|
||||||
# Horizontal line ----
|
|
||||||
shiny::tags$hr(),
|
|
||||||
shiny::radioButtons(
|
|
||||||
inputId = "upload_redcap",
|
|
||||||
label = "Upload directly to REDCap server?",
|
|
||||||
selected = "no",
|
|
||||||
inline = TRUE,
|
|
||||||
choices = list(
|
|
||||||
"No" = "no",
|
|
||||||
"Yes" = "yes"
|
|
||||||
)
|
|
||||||
),
|
|
||||||
shiny::conditionalPanel(
|
|
||||||
condition = "input.upload_redcap=='yes'",
|
|
||||||
shiny::h4("2) Data base upload"),
|
|
||||||
shiny::helpText("This tool is usable for now. Detailed instructions are coming."),
|
|
||||||
shiny::textInput(
|
|
||||||
inputId = "uri",
|
|
||||||
label = "URI",
|
|
||||||
value = "https://redcap.your.institution/api/"
|
|
||||||
),
|
|
||||||
shiny::textInput(
|
|
||||||
inputId = "api",
|
|
||||||
label = "API key",
|
|
||||||
value = ""
|
|
||||||
),
|
|
||||||
shiny::helpText("An API key is an access key to the REDCap database. Please", shiny::a("see here for directions", href = "https://www.iths.org/news/redcap-tip/redcap-api-101/"), " to obtain an API key for your project."),
|
|
||||||
shiny::actionButton(
|
|
||||||
inputId = "upload.meta",
|
|
||||||
label = "Upload datadictionary", icon = shiny::icon("book-bookmark")
|
|
||||||
),
|
|
||||||
shiny::helpText("Please note, that before uploading any real data, put your project
|
|
||||||
into production mode."),
|
|
||||||
shiny::actionButton(
|
|
||||||
inputId = "upload.data",
|
|
||||||
label = "Upload data", icon = shiny::icon("upload")
|
|
||||||
)
|
|
||||||
)
|
|
||||||
),
|
|
||||||
shiny::br(),
|
|
||||||
shiny::br(),
|
|
||||||
shiny::br(),
|
|
||||||
shiny::p(
|
|
||||||
"License: ", shiny::a("GPL-3+", href = "https://agdamsbo.github.io/REDCapCAST/LICENSE.html")
|
|
||||||
),
|
|
||||||
shiny::p(
|
|
||||||
shiny::a("Package documentation", href = "https://agdamsbo.github.io/REDCapCAST")
|
|
||||||
)
|
|
||||||
),
|
|
||||||
bslib::nav_panel(
|
|
||||||
title = "Intro",
|
|
||||||
shiny::markdown(readLines("www/SHINYCAST.md")),
|
|
||||||
shiny::br()
|
|
||||||
),
|
|
||||||
# bslib::nav_spacer(),
|
|
||||||
bslib::nav_panel(
|
|
||||||
title = "Data preview",
|
|
||||||
gt::gt_output(outputId = "data.tbl")
|
|
||||||
# shiny::htmlOutput(outputId = "data.tbl", container = shiny::span)
|
|
||||||
),
|
|
||||||
bslib::nav_panel(
|
|
||||||
title = "Dictionary overview",
|
|
||||||
gt::gt_output(outputId = "meta.tbl")
|
|
||||||
# shiny::htmlOutput(outputId = "meta.tbl", container = shiny::span)
|
|
||||||
),
|
|
||||||
bslib::nav_panel(
|
|
||||||
title = "Upload",
|
|
||||||
shiny::h3("Meta upload overview"),
|
|
||||||
shiny::textOutput(outputId = "upload.meta.print"),
|
|
||||||
shiny::h3("Data upload overview"),
|
|
||||||
shiny::textOutput(outputId = "upload.data.print")
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
% Please edit documentation in R/as_factor.R
|
% Please edit documentation in R/as_factor.R
|
||||||
\name{as_factor}
|
\name{as_factor}
|
||||||
\alias{as_factor}
|
\alias{as_factor}
|
||||||
|
\alias{as_factor.factor}
|
||||||
\alias{as_factor.logical}
|
\alias{as_factor.logical}
|
||||||
\alias{as_factor.numeric}
|
\alias{as_factor.numeric}
|
||||||
\alias{as_factor.character}
|
\alias{as_factor.character}
|
||||||
@ -11,20 +12,43 @@
|
|||||||
\usage{
|
\usage{
|
||||||
as_factor(x, ...)
|
as_factor(x, ...)
|
||||||
|
|
||||||
|
\method{as_factor}{factor}(x, ...)
|
||||||
|
|
||||||
\method{as_factor}{logical}(x, ...)
|
\method{as_factor}{logical}(x, ...)
|
||||||
|
|
||||||
\method{as_factor}{numeric}(x, ...)
|
\method{as_factor}{numeric}(x, ...)
|
||||||
|
|
||||||
\method{as_factor}{character}(x, ...)
|
\method{as_factor}{character}(x, ...)
|
||||||
|
|
||||||
\method{as_factor}{haven_labelled}(x, ...)
|
\method{as_factor}{haven_labelled}(
|
||||||
|
x,
|
||||||
|
levels = c("default", "labels", "values", "both"),
|
||||||
|
ordered = FALSE,
|
||||||
|
...
|
||||||
|
)
|
||||||
|
|
||||||
\method{as_factor}{labelled}(x, ...)
|
\method{as_factor}{labelled}(
|
||||||
|
x,
|
||||||
|
levels = c("default", "labels", "values", "both"),
|
||||||
|
ordered = FALSE,
|
||||||
|
...
|
||||||
|
)
|
||||||
}
|
}
|
||||||
\arguments{
|
\arguments{
|
||||||
\item{x}{Object to coerce to a factor.}
|
\item{x}{Object to coerce to a factor.}
|
||||||
|
|
||||||
\item{...}{Other arguments passed down to method.}
|
\item{...}{Other arguments passed down to method.}
|
||||||
|
|
||||||
|
\item{levels}{How to create the levels of the generated factor:
|
||||||
|
|
||||||
|
* "default": uses labels where available, otherwise the values.
|
||||||
|
Labels are sorted by value.
|
||||||
|
* "both": like "default", but pastes together the level and value
|
||||||
|
* "label": use only the labels; unlabelled values become `NA`
|
||||||
|
* "values": use only the values}
|
||||||
|
|
||||||
|
\item{ordered}{If `TRUE` create an ordered (ordinal) factor, if
|
||||||
|
`FALSE` (the default) create a regular (nominal) factor.}
|
||||||
}
|
}
|
||||||
\description{
|
\description{
|
||||||
This extends [forcats::as_factor()] as well as [haven::as_factor()], by appending
|
This extends [forcats::as_factor()] as well as [haven::as_factor()], by appending
|
||||||
@ -33,19 +57,19 @@ ta loss in case of rich formatted and labelled data.
|
|||||||
}
|
}
|
||||||
\details{
|
\details{
|
||||||
Please refer to parent functions for extended documentation.
|
Please refer to parent functions for extended documentation.
|
||||||
|
To avoid redundancy calls and errors, functions are copy-pasted here
|
||||||
}
|
}
|
||||||
\examples{
|
\examples{
|
||||||
# will preserve all attributes but class
|
# will preserve all attributes
|
||||||
c(1, 4, 3, "A", 7, 8, 1) |> as_factor()
|
c(1, 4, 3, "A", 7, 8, 1) |> as_factor()
|
||||||
structure(c(1, 2, 3, 2, 10, 9),
|
structure(c(1, 2, 3, 2, 10, 9),
|
||||||
labels = c(Unknown = 9, Refused = 10)
|
labels = c(Unknown = 9, Refused = 10)
|
||||||
) |>
|
) |>
|
||||||
as_factor()
|
as_factor() |> dput()
|
||||||
|
|
||||||
structure(c(1, 2, 3, 2, 10, 9),
|
structure(c(1, 2, 3, 2, 10, 9),
|
||||||
labels = c(Unknown = 9, Refused = 10),
|
labels = c(Unknown = 9, Refused = 10),
|
||||||
class = "haven_labelled"
|
class = "haven_labelled"
|
||||||
) |>
|
) |>
|
||||||
as_factor()
|
as_factor()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
17
man/cast_data_overview.Rd
Normal file
17
man/cast_data_overview.Rd
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
% Generated by roxygen2: do not edit by hand
|
||||||
|
% Please edit documentation in R/shiny_cast.R
|
||||||
|
\name{cast_data_overview}
|
||||||
|
\alias{cast_data_overview}
|
||||||
|
\title{Overview of REDCapCAST data for shiny}
|
||||||
|
\usage{
|
||||||
|
cast_data_overview(data)
|
||||||
|
}
|
||||||
|
\arguments{
|
||||||
|
\item{data}{list with class 'REDCapCAST'}
|
||||||
|
}
|
||||||
|
\value{
|
||||||
|
gt object
|
||||||
|
}
|
||||||
|
\description{
|
||||||
|
Overview of REDCapCAST data for shiny
|
||||||
|
}
|
17
man/cast_meta_overview.Rd
Normal file
17
man/cast_meta_overview.Rd
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
% Generated by roxygen2: do not edit by hand
|
||||||
|
% Please edit documentation in R/shiny_cast.R
|
||||||
|
\name{cast_meta_overview}
|
||||||
|
\alias{cast_meta_overview}
|
||||||
|
\title{Overview of REDCapCAST meta data for shiny}
|
||||||
|
\usage{
|
||||||
|
cast_meta_overview(data)
|
||||||
|
}
|
||||||
|
\arguments{
|
||||||
|
\item{data}{list with class 'REDCapCAST'}
|
||||||
|
}
|
||||||
|
\value{
|
||||||
|
gt object
|
||||||
|
}
|
||||||
|
\description{
|
||||||
|
Overview of REDCapCAST meta data for shiny
|
||||||
|
}
|
@ -75,6 +75,7 @@ Ensure, that the data set is formatted with as much information as possible.
|
|||||||
`field.type` can be supplied
|
`field.type` can be supplied
|
||||||
}
|
}
|
||||||
\examples{
|
\examples{
|
||||||
|
\dontrun{
|
||||||
data <- REDCapCAST::redcapcast_data
|
data <- REDCapCAST::redcapcast_data
|
||||||
data |> ds2dd_detailed()
|
data |> ds2dd_detailed()
|
||||||
iris |> ds2dd_detailed(add.auto.id = TRUE)
|
iris |> ds2dd_detailed(add.auto.id = TRUE)
|
||||||
@ -92,3 +93,4 @@ names(data) <- glue::glue("{sample(x = c('a','b'),size = length(names(data)),
|
|||||||
replace=TRUE,prob = rep(x=.5,2))}__{names(data)}")
|
replace=TRUE,prob = rep(x=.5,2))}__{names(data)}")
|
||||||
data |> ds2dd_detailed(form.sep = "__")
|
data |> ds2dd_detailed(form.sep = "__")
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
@ -17,7 +17,8 @@ Allows conversion of factor to numeric values preserving original levels
|
|||||||
}
|
}
|
||||||
\examples{
|
\examples{
|
||||||
c(1, 4, 3, "A", 7, 8, 1) |>
|
c(1, 4, 3, "A", 7, 8, 1) |>
|
||||||
as_factor() |> fct2num()
|
as_factor() |>
|
||||||
|
fct2num()
|
||||||
|
|
||||||
structure(c(1, 2, 3, 2, 10, 9),
|
structure(c(1, 2, 3, 2, 10, 9),
|
||||||
labels = c(Unknown = 9, Refused = 10),
|
labels = c(Unknown = 9, Refused = 10),
|
||||||
@ -27,8 +28,21 @@ structure(c(1, 2, 3, 2, 10, 9),
|
|||||||
fct2num()
|
fct2num()
|
||||||
|
|
||||||
structure(c(1, 2, 3, 2, 10, 9),
|
structure(c(1, 2, 3, 2, 10, 9),
|
||||||
labels = c(Unknown = 9, Refused = 10)
|
labels = c(Unknown = 9, Refused = 10),
|
||||||
|
class = "labelled"
|
||||||
) |>
|
) |>
|
||||||
as_factor() |>
|
as_factor() |>
|
||||||
fct2num()
|
fct2num()
|
||||||
|
|
||||||
|
# Outlier with labels, but no class of origin, handled like numeric vector
|
||||||
|
# structure(c(1, 2, 3, 2, 10, 9),
|
||||||
|
# labels = c(Unknown = 9, Refused = 10)
|
||||||
|
# ) |>
|
||||||
|
# as_factor() |>
|
||||||
|
# fct2num()
|
||||||
|
|
||||||
|
v <- sample(6:19,20,TRUE) |> factor()
|
||||||
|
dput(v)
|
||||||
|
named_levels(v)
|
||||||
|
fct2num(v)
|
||||||
}
|
}
|
||||||
|
@ -19,9 +19,10 @@ Extract attribute. Returns NA if none
|
|||||||
}
|
}
|
||||||
\examples{
|
\examples{
|
||||||
attr(mtcars$mpg, "label") <- "testing"
|
attr(mtcars$mpg, "label") <- "testing"
|
||||||
sapply(mtcars, get_attr)
|
do.call(c, sapply(mtcars, get_attr))
|
||||||
lapply(mtcars, \(.x)get_attr(.x, NULL))
|
\dontrun{
|
||||||
mtcars |>
|
mtcars |>
|
||||||
numchar2fct(numeric.threshold = 6) |>
|
numchar2fct(numeric.threshold = 6) |>
|
||||||
ds2dd_detailed()
|
ds2dd_detailed()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
@ -10,6 +10,11 @@ named_levels(data, label = "labels", na.label = NULL, na.value = 99)
|
|||||||
\item{data}{factor}
|
\item{data}{factor}
|
||||||
|
|
||||||
\item{label}{character string of attribute with named vector of factor labels}
|
\item{label}{character string of attribute with named vector of factor labels}
|
||||||
|
|
||||||
|
\item{na.label}{character string to refactor NA values. Default is NULL.}
|
||||||
|
|
||||||
|
\item{na.value}{new value for NA strings. Ignored if na.label is NULL.
|
||||||
|
Default is 99.}
|
||||||
}
|
}
|
||||||
\value{
|
\value{
|
||||||
named vector
|
named vector
|
||||||
@ -18,8 +23,12 @@ named vector
|
|||||||
Get named vector of factor levels and values
|
Get named vector of factor levels and values
|
||||||
}
|
}
|
||||||
\examples{
|
\examples{
|
||||||
|
\dontrun{
|
||||||
structure(c(1, 2, 3, 2, 10, 9),
|
structure(c(1, 2, 3, 2, 10, 9),
|
||||||
labels = c(Unknown = 9, Refused = 10),
|
labels = c(Unknown = 9, Refused = 10),
|
||||||
class = "haven_labelled"
|
class = "haven_labelled"
|
||||||
) |> as_factor() |> named_levels()
|
) |>
|
||||||
|
as_factor() |>
|
||||||
|
named_levels()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
14
man/nav_bar_page.Rd
Normal file
14
man/nav_bar_page.Rd
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
% Generated by roxygen2: do not edit by hand
|
||||||
|
% Please edit documentation in R/shiny_cast.R
|
||||||
|
\name{nav_bar_page}
|
||||||
|
\alias{nav_bar_page}
|
||||||
|
\title{Nav_bar defining function for shiny ui}
|
||||||
|
\usage{
|
||||||
|
nav_bar_page()
|
||||||
|
}
|
||||||
|
\value{
|
||||||
|
shiny object
|
||||||
|
}
|
||||||
|
\description{
|
||||||
|
Nav_bar defining function for shiny ui
|
||||||
|
}
|
@ -23,7 +23,9 @@ Individual thresholds for character and numeric columns
|
|||||||
}
|
}
|
||||||
\examples{
|
\examples{
|
||||||
mtcars |> str()
|
mtcars |> str()
|
||||||
|
\dontrun{
|
||||||
mtcars |>
|
mtcars |>
|
||||||
numchar2fct(numeric.threshold = 6) |>
|
numchar2fct(numeric.threshold = 6) |>
|
||||||
str()
|
str()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
@ -33,7 +33,9 @@ data.frame or tibble
|
|||||||
Helper to auto-parse un-formatted data with haven and readr
|
Helper to auto-parse un-formatted data with haven and readr
|
||||||
}
|
}
|
||||||
\examples{
|
\examples{
|
||||||
|
\dontrun{
|
||||||
mtcars |>
|
mtcars |>
|
||||||
parse_data() |>
|
parse_data() |>
|
||||||
str()
|
str()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
\alias{set_attr}
|
\alias{set_attr}
|
||||||
\title{Set attributes for named attribute. Appends if attr is NULL}
|
\title{Set attributes for named attribute. Appends if attr is NULL}
|
||||||
\usage{
|
\usage{
|
||||||
set_attr(data, label, attr = NULL)
|
set_attr(data, label, attr = NULL, overwrite = FALSE)
|
||||||
}
|
}
|
||||||
\arguments{
|
\arguments{
|
||||||
\item{data}{vector}
|
\item{data}{vector}
|
||||||
@ -12,6 +12,8 @@ set_attr(data, label, attr = NULL)
|
|||||||
\item{label}{label}
|
\item{label}{label}
|
||||||
|
|
||||||
\item{attr}{attribute name}
|
\item{attr}{attribute name}
|
||||||
|
|
||||||
|
\item{overwrite}{overwrite existing attributes. Default is FALSE.}
|
||||||
}
|
}
|
||||||
\value{
|
\value{
|
||||||
vector with attribute
|
vector with attribute
|
||||||
|
@ -19,6 +19,7 @@ This is a wrapper of forcats::as_factor, which sorts numeric vectors before
|
|||||||
factoring, but levels character vectors in order of appearance.
|
factoring, but levels character vectors in order of appearance.
|
||||||
}
|
}
|
||||||
\examples{
|
\examples{
|
||||||
|
\dontrun{
|
||||||
sample(seq_len(4), 20, TRUE) |>
|
sample(seq_len(4), 20, TRUE) |>
|
||||||
var2fct(6) |>
|
var2fct(6) |>
|
||||||
summary()
|
summary()
|
||||||
@ -27,3 +28,4 @@ sample(letters, 20) |>
|
|||||||
summary()
|
summary()
|
||||||
sample(letters[1:4], 20, TRUE) |> var2fct(6)
|
sample(letters[1:4], 20, TRUE) |> var2fct(6)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
@ -69,11 +69,6 @@ redcapcast_data |>
|
|||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
```{r}
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
Column classes can be passed to `parse_data()`.
|
Column classes can be passed to `parse_data()`.
|
||||||
|
|
||||||
Making a few crude assumption for factorising data, `numchar2fct()` factorises numerical and character vectors based on a set threshold for unique values:
|
Making a few crude assumption for factorising data, `numchar2fct()` factorises numerical and character vectors based on a set threshold for unique values:
|
||||||
|
Loading…
Reference in New Issue
Block a user