-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Richard Hanna
authored and
Richard Hanna
committed
Jul 19, 2022
0 parents
commit 3ae357b
Showing
28 changed files
with
1,678 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
^renv$ | ||
^renv\.lock$ | ||
^.*\.Rproj$ | ||
^\.Rproj\.user$ | ||
^LICENSE\.md$ | ||
^README\.Rmd$ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
source("renv/activate.R") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
.Rproj.user | ||
.Rhistory | ||
.RData | ||
.Ruserdata |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
Package: REDCapTidieR | ||
Type: Package | ||
Title: Extract REDCap Databases into Tidy Tibbles | ||
Version: 0.0.0.9000 | ||
Author: c( | ||
person("Richard", "Hanna", , "[email protected]", role = c("aut", "cre")), | ||
person("Stephan", "Kadauke", , "[email protected]", role = "aut") | ||
) | ||
Maintainer: The package maintainer <[email protected]> | ||
Description: This package is designed to help convert REDCap exports into tidy tables for easy handling of REDCap repeat instruments and event arms. | ||
License: MIT + file LICENSE | ||
Encoding: UTF-8 | ||
LazyData: true | ||
Imports: | ||
checkmate, | ||
dplyr, | ||
purrr, | ||
REDCapR, | ||
stringr | ||
RoxygenNote: 7.2.0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
YEAR: 2022 | ||
COPYRIGHT HOLDER: REDCapTidieR authors |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
# MIT License | ||
|
||
Copyright (c) 2022 REDCapTidieR authors | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
# Generated by roxygen2: do not edit by hand | ||
|
||
export(read_redcap_tidy) | ||
import(REDCapR) | ||
import(checkmate) | ||
import(dplyr) | ||
import(purrr) | ||
import(stringr) | ||
import(tibble) | ||
import(tidyr) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
#' Extract non-Longitudinal REDCap Databases into Tidy Tibbles | ||
#' | ||
#' @param db_data The REDCap database output defined by \code{REDCapR::reedcap_read_oneshot()$data} | ||
#' @param db_metadata The REDCap metadata output defined by \code{REDCapR::redcap_metadata_read()$data} | ||
#' | ||
#' @import dplyr purrr REDCapR checkmate | ||
|
||
clean_redcap <- function( | ||
db_data, | ||
db_metadata | ||
){ | ||
|
||
# Apply checkmate checks --- | ||
assert_data_frame(db_data) | ||
assert_data_frame(db_metadata) | ||
|
||
repeated_forms <- db_data %>% | ||
filter(!is.na(redcap_repeat_instrument)) %>% | ||
pull(redcap_repeat_instrument) %>% | ||
unique() | ||
|
||
repeated_forms_tibble <- tibble( | ||
names = repeated_forms, | ||
data = map( | ||
repeated_forms, | ||
~ extract_repeat_table(.x, db_data, db_metadata) | ||
), | ||
structure = "repeating" | ||
) | ||
|
||
nonrepeated_forms <- db_metadata %>% | ||
pull(form_name) %>% | ||
unique() %>% | ||
setdiff(repeated_forms) | ||
|
||
nonrepeated_forms_tibble <- tibble( | ||
names = nonrepeated_forms, | ||
data = map( | ||
nonrepeated_forms, | ||
~ extract_nonrepeat_table(.x, db_data, db_metadata) | ||
), | ||
structure = "nonrepeating" | ||
) | ||
|
||
clean_redcap_output <- rbind(repeated_forms_tibble, nonrepeated_forms_tibble) | ||
|
||
clean_redcap_output | ||
} | ||
|
||
#' Extract Non-Repeat Tables from non-Longitudinal REDCap Databases | ||
#' | ||
#' @param form_name The \code{form_name} described in the named column from the REDCap metadata. | ||
#' @param db_data The REDCap database output defined by \code{REDCapR::reedcap_read_oneshot()$data} | ||
#' @param db_metadata The REDCap metadata output defined by \code{REDCapR::redcap_metadata_read()$data} | ||
#' | ||
#' @import dplyr REDCapR | ||
|
||
extract_nonrepeat_table <- function( | ||
form_name, | ||
db_data, | ||
db_metadata | ||
){ | ||
my_record_id <- names(db_data)[1] | ||
my_form <- form_name | ||
|
||
my_fields <- db_metadata %>% | ||
filter(form_name == my_form) %>% | ||
pull(field_name) | ||
|
||
if (my_fields[1] != my_record_id) { | ||
my_fields <- c(my_record_id, my_fields) | ||
} | ||
|
||
db_data %>% | ||
filter(is.na(redcap_repeat_instance)) %>% | ||
select(all_of(my_fields)) | ||
} | ||
|
||
#' Extract Repeat Tables from non-Longitudinal REDCap Databases | ||
#' | ||
#' @param form_name The \code{form_name} described in the named column from the REDCap metadata. | ||
#' @param db_data The non-longitudinal REDCap database output defined by \code{REDCapR::redcap_read_oneshot()$data} | ||
#' @param db_metadata The non-longitudinal REDCap metadata output defined by \code{REDCapR::redcap_metadata_read()$data} | ||
#' | ||
#' @import dplyr REDCapR | ||
|
||
extract_repeat_table <- function( | ||
form_name, | ||
db_data, | ||
db_metadata | ||
){ | ||
my_record_id <- names(db_data)[1] | ||
my_form <- form_name | ||
|
||
my_fields <- db_metadata %>% | ||
filter(form_name == my_form) %>% | ||
pull(field_name) | ||
|
||
if (my_fields[1] != my_record_id) { | ||
my_fields <- c(my_record_id, my_fields) | ||
} | ||
|
||
db_data %>% | ||
filter(!is.na(redcap_repeat_instance)) %>% | ||
select(all_of(my_fields), redcap_repeat_instance) %>% | ||
relocate(redcap_repeat_instance, .after = all_of(my_record_id)) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,162 @@ | ||
#' Extract Longitudinal REDCap Databases into Tidy Tibbles | ||
#' | ||
#' @param db_data_long The longitudinal REDCap database output defined by \code{REDCapR::redcap_read_oneshot()$data} | ||
#' @param db_metadata_long The longitudinal REDCap metadata output defined by \code{REDCapR::redcap_metadata_read()$data} | ||
#' @param linked_arms Output of \code{link_arms}, linking forms to REDCap events/arms | ||
#' | ||
#' @import dplyr purrr REDCapR checkmate | ||
|
||
clean_redcap_long <- function( | ||
db_data_long, | ||
db_metadata_long, | ||
linked_arms | ||
){ | ||
|
||
# Apply checkmate checks | ||
assert_data_frame(db_data_long) | ||
assert_data_frame(db_metadata_long) | ||
|
||
## Repeating Forms Logic ---- | ||
repeated_forms <- db_data_long %>% | ||
filter(!is.na(redcap_repeat_instrument)) %>% | ||
pull(redcap_repeat_instrument) %>% | ||
unique() | ||
|
||
repeated_forms_tibble <- tibble( | ||
redcap_form_names = repeated_forms, | ||
redcap_data = map( | ||
redcap_form_names, | ||
~ extract_repeat_table_long(.x, db_data_long, db_metadata_long, linked_arms) | ||
), | ||
structure = "repeating" | ||
) | ||
|
||
## Nonrepeating Forms Logic ---- | ||
nonrepeated_forms <- db_metadata_long %>% | ||
pull(form_name) %>% | ||
unique() %>% | ||
setdiff(repeated_forms) | ||
|
||
nonrepeated_forms_tibble <- tibble( | ||
redcap_form_names = nonrepeated_forms, | ||
redcap_data = map( | ||
redcap_form_names, | ||
~ extract_nonrepeat_table_long(.x, db_data_long, db_metadata_long, linked_arms) | ||
), | ||
structure = "nonrepeating" | ||
) | ||
|
||
clean_redcap_output <- rbind(repeated_forms_tibble, nonrepeated_forms_tibble) | ||
|
||
clean_redcap_output | ||
} | ||
|
||
#' Extract Non-Repeat Tables from Longitudinal REDCap Databases | ||
#' | ||
#' @param form_name The \code{form_name} described in the named column from the REDCap metadata. | ||
#' @param db_data The REDCap database output defined by \code{REDCapR::reedcap_read_oneshot()$data} | ||
#' @param db_metadata The REDCap metadata output defined by \code{REDCapR::redcap_metadata_read()$data} | ||
#' @param linked_arms Output of \code{link_arms}, linking forms to REDCap events/arms | ||
#' | ||
#' @import dplyr REDCapR stringr | ||
|
||
extract_nonrepeat_table_long <- function( | ||
form_name, | ||
db_data_long, | ||
db_metadata_long, | ||
linked_arms | ||
){ | ||
my_record_id <- names(db_data_long)[1] | ||
my_form <- form_name | ||
|
||
my_fields <- db_metadata_long %>% | ||
filter(form_name == my_form) %>% | ||
pull(field_name) | ||
|
||
if (my_fields[1] != my_record_id) { | ||
my_fields <- c(my_record_id, my_fields) | ||
} | ||
|
||
# Setup data for loop redcap_arm linking | ||
db_data_long <- db_data_long %>% | ||
add_partial_keys() %>% | ||
filter(is.na(redcap_repeat_instance)) | ||
|
||
# Use link_arms() output to check if my_form appears in each event_name | ||
# If it does not, filter out all rows containing that event_name | ||
for (i in 1:length(names(linked_arms))) { | ||
if (my_form %in% unlist(linked_arms[[i]]) == FALSE) { | ||
db_data_long <- db_data_long %>% | ||
filter(redcap_event_name != names(linked_arms[i])) | ||
} | ||
db_data_long | ||
} | ||
|
||
# Final aesthetic cleanup | ||
out <- db_data_long %>% | ||
select(all_of(my_fields), redcap_event, redcap_arm) %>% | ||
relocate(c(redcap_event, redcap_arm), .after = record_id) | ||
|
||
# Check arms | ||
if(any(names(linked_arms) %>% str_detect("arm_2"))){ | ||
out <- out %>% | ||
select(-redcap_arm) | ||
} | ||
|
||
out | ||
} | ||
|
||
#' Extract Repeat Tables from Longitudinal REDCap Databases | ||
#' | ||
#' @param form_name The \code{form_name} described in the named column from the REDCap metadata. | ||
#' @param db_data The REDCap database output defined by \code{REDCapR::reedcap_read_oneshot()$data} | ||
#' @param db_metadata The REDCap metadata output defined by \code{REDCapR::redcap_metadata_read()$data} | ||
#' @param linked_arms Output of \code{link_arms}, linking forms to REDCap events/arms | ||
#' | ||
#' @import dplyr REDCapR stringr | ||
|
||
extract_repeat_table_long <- function( | ||
form_name, | ||
db_data_long, | ||
db_metadata_long, | ||
linked_arms | ||
){ | ||
my_record_id <- names(db_data_long)[1] | ||
my_form <- form_name | ||
|
||
my_fields <- db_metadata_long %>% | ||
filter(form_name == my_form) %>% | ||
pull(field_name) | ||
|
||
if (my_fields[1] != my_record_id) { | ||
my_fields <- c(my_record_id, my_fields) | ||
} | ||
|
||
# Setup data for loop redcap_arm linking | ||
db_data_long <- db_data_long %>% | ||
add_partial_keys() %>% | ||
filter(!is.na(redcap_repeat_instance)) | ||
|
||
# Use link_arms() output to check if my_form appears in each event_name | ||
# If it does not, filter out all rows containing that event_name | ||
for (i in 1:length(names(linked_arms))) { | ||
if (my_form %in% unlist(linked_arms[[i]]) == FALSE) { | ||
db_data_long <- db_data_long %>% | ||
filter(redcap_event_name != names(linked_arms[i])) | ||
} | ||
db_data_long | ||
} | ||
|
||
# Final aesthetic cleanup | ||
out <- db_data_long %>% | ||
select(all_of(my_fields), redcap_repeat_instance, redcap_event, redcap_arm) %>% | ||
relocate(c(redcap_repeat_instance, redcap_event, redcap_arm), .after = record_id) | ||
|
||
# Check arms | ||
if(any(names(linked_arms) %>% str_detect("arm_2"))){ | ||
out <- out %>% | ||
select(-redcap_arm) | ||
} | ||
|
||
out | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
#' Extract REDCap Databases to Tidy Tibbles | ||
#' | ||
#' Automatically detect REDCap database structure for the following elements: | ||
#' \itemize{ | ||
#' \item{Repeat Instruments} | ||
#' \item{Longitudinal Events} | ||
#' \item{Longitudinal Arms} | ||
#' } | ||
#' | ||
#' @import REDCapR | ||
#' | ||
#' @param redcap_uri The URI (uniform resource identifier) of the REDCap project. Required. | ||
#' @param token The user-specific string that serves as the password for a project. Required. | ||
#' | ||
#' @export | ||
|
||
read_redcap_tidy <- function(redcap_uri, | ||
token){ | ||
|
||
# Load Datasets ---- | ||
db_data <- redcap_read_oneshot(redcap_uri = redcap_uri, | ||
token = token)$data | ||
|
||
db_metadata <- redcap_metadata_read(redcap_uri = redcap_uri, | ||
token = token)$data | ||
|
||
# Check if database supplied is longitudinal to determine appropriate function to use | ||
is_longitudinal <- if("redcap_event_name" %in% names(db_data)){TRUE}else{FALSE} | ||
|
||
if (is_longitudinal) { | ||
linked_arms <- link_arms(db_data_long = db_data, | ||
db_metadata_long = db_metadata, | ||
redcap_uri = redcap_uri, | ||
token = token) | ||
|
||
out <- clean_redcap_long(db_data_long = db_data, | ||
db_metadata_long = db_metadata, | ||
linked_arms = linked_arms) | ||
} else { | ||
out <- clean_redcap(db_data = db_data, | ||
db_metadata = db_metadata) | ||
} | ||
|
||
out | ||
} |
Oops, something went wrong.