diff --git a/.Rbuildignore b/.Rbuildignore index de5a9c5..3ecebbb 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -9,3 +9,4 @@ ^\.travis\.yml$ ^doc$ ^Meta$ +^.github/ \ No newline at end of file diff --git a/.github/.gitignore b/.github/.gitignore new file mode 100644 index 0000000..2d19fc7 --- /dev/null +++ b/.github/.gitignore @@ -0,0 +1 @@ +*.html diff --git a/.github/workflows/pkgdown.yaml b/.github/workflows/pkgdown.yaml new file mode 100644 index 0000000..ed7650c --- /dev/null +++ b/.github/workflows/pkgdown.yaml @@ -0,0 +1,48 @@ +# Workflow derived from https://github.com/r-lib/actions/tree/v2/examples +# Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help +on: + push: + branches: [main, master] + pull_request: + branches: [main, master] + release: + types: [published] + workflow_dispatch: + +name: pkgdown + +jobs: + pkgdown: + runs-on: ubuntu-latest + # Only restrict concurrency for non-PR jobs + concurrency: + group: pkgdown-${{ github.event_name != 'pull_request' || github.run_id }} + env: + GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} + permissions: + contents: write + steps: + - uses: actions/checkout@v3 + + - uses: r-lib/actions/setup-pandoc@v2 + + - uses: r-lib/actions/setup-r@v2 + with: + use-public-rspm: true + + - uses: r-lib/actions/setup-r-dependencies@v2 + with: + extra-packages: any::pkgdown, local::. + needs: website + + - name: Build site + run: pkgdown::build_site_github_pages(new_process = FALSE, install = FALSE) + shell: Rscript {0} + + - name: Deploy to GitHub pages π + if: github.event_name != 'pull_request' + uses: JamesIves/github-pages-deploy-action@v4.4.1 + with: + clean: false + branch: gh-pages + folder: docs diff --git a/.gitignore b/.gitignore index 5692018..31f999f 100644 --- a/.gitignore +++ b/.gitignore @@ -44,3 +44,7 @@ inst/doc **/.DS_Store doc Meta + +# pkgdown rendering +docs/ +inst/docs/ diff --git a/DESCRIPTION b/DESCRIPTION index 24d8faa..bc27b53 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: tidyREDCap Title: Helper Functions for Working with 'REDCap' Data -Version: 1.1.2 +Version: 1.1.3 Authors@R: c(person( given = "Raymond", @@ -58,8 +58,8 @@ Description: developed at Vanderbilt University. License: MIT + file LICENSE Encoding: UTF-8 -RoxygenNote: 7.3.2 -Depends: R (>= 3.5.0) +RoxygenNote: 7.3.3 +Depends: R (>= 4.1.0) Imports: cli, dplyr, diff --git a/NEWS.md b/NEWS.md index 5c8df42..5f404a9 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,9 @@ +# tidyREDCap 1.1.3 (CRAN release) + +* Package now depends on R >= 4.1.0 for use of pipe operator. +* Fixed vignette URLs that were causing site redirection issues with automated CRAN checks. +* Added alt text to vignette images. + # tidyREDCap 1.1.2 (CRAN release) * Fix issues reported by CRAN with Linux and old R Windows (4.3.3) saying diff --git a/R/make_instrument_auto.R b/R/make_instrument_auto.R index 43af055..3270e23 100644 --- a/R/make_instrument_auto.R +++ b/R/make_instrument_auto.R @@ -13,20 +13,24 @@ #' @export #' ## @examples -make_instrument_auto <- function(df, drop_which_when = FALSE, - record_id = "record_id") { +make_instrument_auto <- function( + df, + drop_which_when = FALSE, + record_id = "record_id" +) { if (names(df)[1] != record_id) { - stop(" + stop( + " The first variable in df must be `record_id`; - use option 'record_id=' to set the name of your custom id.", call. = FALSE) + use option 'record_id=' to set the name of your custom id.", + call. = FALSE + ) } - # Strip labels from REDCap created variables to prevent reported join (and # perhaps pivot) issues on labeled variables. df <- drop_label(df, record_id) - is_longitudinal <- any(names(df) == "redcap_event_name") if (is_longitudinal) { @@ -69,37 +73,49 @@ make_instrument_auto <- function(df, drop_which_when = FALSE, record_id_col <- which(colnames(df) == record_id) redcap_event_name_col <- which(colnames(df) == "redcap_event_name") record_repeat_inst_col <- which(colnames(df) == "redcap_repeat_instance") - + if (is_longitudinal) { - # Select rows that have data with a repeat number - if (is_repeated & !all(is.na(df[!allMissing,record_repeat_inst_col]))) { - return(df[!allMissing, c( - record_id_col, - redcap_event_name_col, - record_repeat_inst_col, - first_col:last_col - )]) + # Select rows that have data with a repeat number + if (is_repeated & !all(is.na(df[!allMissing, record_repeat_inst_col]))) { + return(df[ + !allMissing, + c( + record_id_col, + redcap_event_name_col, + record_repeat_inst_col, + first_col:last_col + ) + ]) } else { # Longitudinal not repeated instruments - return(df[!allMissing, c( - record_id_col, - redcap_event_name_col, - first_col:last_col - )]) + return(df[ + !allMissing, + c( + record_id_col, + redcap_event_name_col, + first_col:last_col + ) + ]) } } else { - # Select rows that have data with a repeat number - if (is_repeated & !all(is.na(df[!allMissing,record_repeat_inst_col]))) { - return(df[!allMissing, c( - record_id_col, - record_repeat_inst_col, - first_col:last_col - )]) + # Select rows that have data with a repeat number + if (is_repeated & !all(is.na(df[!allMissing, record_repeat_inst_col]))) { + return(df[ + !allMissing, + c( + record_id_col, + record_repeat_inst_col, + first_col:last_col + ) + ]) } else { - return(df[!allMissing, c( - record_id_col, - first_col:last_col - )]) + return(df[ + !allMissing, + c( + record_id_col, + first_col:last_col + ) + ]) } } } else { @@ -157,19 +173,43 @@ fix_class_bug <- function(df) { "fix_class_bug" -#' Drop the label from a variable -#' @description There is a reported issues with joins on data (without a reprex) -#' that seem to be caused by the labels. As a possible solution this can be -#' used to drop labels. +#' Drop the label from one or more variables +#' @description There is a reported issue with joins on data (without a reprex) +#' that seem to be caused by the labels. As a possible solution this can be +#' used to drop labels from one or more variables. #' #' @param df the name of the data frame -#' @param x the quoted name of the variable +#' @param ... Variable selection using tidyselect helpers (e.g., `contains()`, +#' `starts_with()`) or column names as symbols or strings #' -#' @export +#' @examples +#' \dontrun{ +#' # Remove labels from a single variable +#' df |> drop_label(employment) #' +#' # Remove labels from multiple variables +#' df |> drop_label(employment, marital_status) #' -#' @return df -drop_label <- function(df, x) { - attributes(df[, which(names(df) == x)]) <- NULL +#' # Remove all demograhic labels using tidyselect helpers +#' df |> drop_label(starts_with("dem_")) +#' } +#' +#' @export +#' +#' @return df with labels removed from selected variables +drop_label <- function(df, ...) { + # Capture the variables using tidyselect + vars_idx <- tidyselect::eval_select(rlang::expr(c(...)), df) + + # If no variables selected, return the dataframe as is + if (length(vars_idx) == 0) return(df) + + # For each selected column, remove its attributes + for (col_idx in vars_idx) { + attributes(df[[col_idx]]) <- NULL + } + + # TODO: investigate if labelled class needs to be dropped + df } diff --git a/docs/404.html b/docs/404.html deleted file mode 100644 index 90992db..0000000 --- a/docs/404.html +++ /dev/null @@ -1,140 +0,0 @@ - - -
- - - - -YEAR: 2020 -COPYRIGHT HOLDER: Raymond Balise -- -
Copyright (c) 2020 Raymond Balise
-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.
-The tidyREDCap package creates data sets with labelled
-columns.
-tidyREDCap::import_instruments(
- url = "https://bbmc.ouhsc.edu/redcap/api/",
- token = Sys.getenv("REDCapR_test")
-)If you would like to see the labels on the data set
-demographics, you can use the RStudio function
-View(), as shown below.
-View(demographics)
However, some functions do not work well with labeled variables.
- -| Name | -demographics | -
| Number of rows | -5 | -
| Number of columns | -10 | -
| _______________________ | -- |
| Column type frequency: | -- |
| character | -7 | -
| Date | -1 | -
| numeric | -2 | -
| ________________________ | -- |
| Group variables | -None | -
Variable type: character
-| skim_variable | -n_missing | -complete_rate | -min | -max | -empty | -n_unique | -whitespace | -
|---|---|---|---|---|---|---|---|
| name_first | -0 | -1 | -5 | -8 | -0 | -5 | -0 | -
| name_last | -0 | -1 | -3 | -8 | -0 | -4 | -0 | -
| address | -0 | -1 | -29 | -38 | -0 | -5 | -0 | -
| telephone | -0 | -1 | -14 | -14 | -0 | -5 | -0 | -
| 0 | -1 | -12 | -19 | -0 | -5 | -0 | -|
| sex | -0 | -1 | -4 | -6 | -0 | -2 | -0 | -
| demographics_complete | -0 | -1 | -8 | -8 | -0 | -1 | -0 | -
Variable type: Date
-| skim_variable | -n_missing | -complete_rate | -min | -max | -median | -n_unique | -
|---|---|---|---|---|---|---|
| dob | -0 | -1 | -1934-04-09 | -2003-08-30 | -1955-04-15 | -5 | -
Variable type: numeric
-| skim_variable | -n_missing | -complete_rate | -mean | -sd | -p0 | -p25 | -p50 | -p75 | -p100 | -hist | -
|---|---|---|---|---|---|---|---|---|---|---|
| record_id | -0 | -1 | -3.0 | -1.58 | -1 | -2 | -3 | -4 | -5 | -βββββ | -
| age | -0 | -1 | -44.4 | -31.57 | -11 | -11 | -59 | -61 | -80 | -βββββ | -
So you need a way to drop the label off of a variable or to drop all -the labels from all the variables in a dataset.
-You can drop the label from a single variable with the drop_label() -function. For example:
-
-demographics_changed <- drop_label(demographics, "first_name")You can drop all the labels using the drop_labels()
-function. For example:
-demographics_without_labels <- drop_labels(demographics)
-
-demographics_without_labels |>
- skim()| Name | -demographics_without_labe⦠| -
| Number of rows | -5 | -
| Number of columns | -10 | -
| _______________________ | -- |
| Column type frequency: | -- |
| character | -7 | -
| numeric | -3 | -
| ________________________ | -- |
| Group variables | -None | -
Variable type: character
-| skim_variable | -n_missing | -complete_rate | -min | -max | -empty | -n_unique | -whitespace | -
|---|---|---|---|---|---|---|---|
| name_first | -0 | -1 | -5 | -8 | -0 | -5 | -0 | -
| name_last | -0 | -1 | -3 | -8 | -0 | -4 | -0 | -
| address | -0 | -1 | -29 | -38 | -0 | -5 | -0 | -
| telephone | -0 | -1 | -14 | -14 | -0 | -5 | -0 | -
| 0 | -1 | -12 | -19 | -0 | -5 | -0 | -|
| sex | -0 | -1 | -4 | -6 | -0 | -2 | -0 | -
| demographics_complete | -0 | -1 | -8 | -8 | -0 | -1 | -0 | -
Variable type: numeric
-| skim_variable | -n_missing | -complete_rate | -mean | -sd | -p0 | -p25 | -p50 | -p75 | -p100 | -hist | -
|---|---|---|---|---|---|---|---|---|---|---|
| record_id | -0 | -1 | -3.0 | -1.58 | -1 | -2 | -3 | -4 | -5 | -βββββ | -
| dob | -0 | -1 | --56.0 | -11581.94 | --13051 | --6269 | --5375 | -12121 | -12294 | -βββββ | -
| age | -0 | -1 | -44.4 | -31.57 | -11 | -11 | -59 | -61 | -80 | -βββββ | -
vignettes/import_instruments.Rmd
- import_instruments.Rmd
-Figure 1 -
-The same functionality should help deal with instruments that are
-potentially given repeatedly. Common examples include asking
-participants to fill out a form describing medical conditions for all
-their siblings or asking them to fill out a form for each side effect
-they experience while using a drug. In these cases, each participant may
-have zero or many records. Again, creating a table with all the records
-for these βrepeatedβ instruments would be good.
-# Do not type your API token directly into your code
-tidyREDCap::import_instruments(
- url = "https://redcap.miami.edu/api/",
- token = "1A2B3CXXYYZZOOMMGOSHNOOOOX1Y2Z3" # This is BAD!
-)
-
-# A better way to do this is to read the API key from the .Renviron file.
-# For instructions on saving your API key, see link below.
-tidyREDCap::import_instruments(
- url = "https://redcap.miami.edu/api/",
- token = Sys.getenv("nacho_anxiety_key") # This is BETTER!
-)See the Importing from REDCap -vignette for details/information for saving your API key in the -.Renviron file.
-The import_instruments() function can be given a URL and
-token for a REDCap project, like the one created above and it will
-return one table for each instrument in a project. By default, the
-function will drop all empty records. For example, the above API call is
-pulling data from a REDCap project that has four instruments:
-Enrollment, the Nacho Craving Index (NCI), the Generalized Anxiety
-Disorder Assessment (GAD7), and the Hamilton Anxiety Scale (HAM-A).
After running the above code we get four tables from the REDCap -project.
-
Notice that each repeat of the HAM-A is its own record.
-
If a person has only done the baseline assessment they will only have -one record.
-REDCap exports a βchoose all that applyβ question into a series of -similarly-named, binary indicator variables (i.e., the variables are -equal to either βcheckedβ or βuncheckedβ). Using these variables -individually, there is no obvious way to detect common patterns people -pick together.
---Example: In the Nacho Craving Index (NCI), -respondents can indicate which of eight ingredients they are currently -craving (i.e., Chips, Yellow cheese, Orange cheese, White cheese, Meat, -Beans, Tomatoes, Peppers). These are exported into variables with names -like
-ingredients___1,ingredients___2, -etc.
In REDCap, it is simple to get a summary of those individual
-variables by using the βData Exports, Reports, and Statsβ application
-within the REDCap interface and selecting βStats & Chartsβ. Once the
-data is in R, simple tables can be produced with the
-table() function, or beautiful tables can be created with
-the tabyl() and adorn_pct_formatting()
-functions from the janitor package. However, from these
-univariate tables, it is impossible to judge which patterns of answers
-are marked together. In the above example, using the univariate tables,
-it is difficult to tell what percentage of people are craving both chips
-and yellow cheese.
-redcap <- readRDS(file = "./redcap.rds")
-
-# Chips
-janitor::tabyl(redcap$ingredients___1) %>%
- janitor::adorn_pct_formatting() %>%
- knitr::kable()| redcap$ingredients___1 | -n | -percent | -
|---|---|---|
| Unchecked | -21 | -70.0% | -
| Checked | -9 | -30.0% | -
-
-# Yellow cheese
-janitor::tabyl(redcap$ingredients___2) %>%
- janitor::adorn_pct_formatting() %>%
- knitr::kable()| redcap$ingredients___2 | -n | -percent | -
|---|---|---|
| Unchecked | -23 | -76.7% | -
| Checked | -7 | -23.3% | -
See the Import All -Instruments from a REDCap Project and Importing from REDCap vignettes for -details/information.
-Even after subsetting the REDCap data to only include the ingredients -variables, it is still difficult to detect common patterns in the eight -ingredients.
-
-redcap <- readRDS(file = "./redcap.rds")
-
-analysis <- redcap %>%
- select(starts_with("ingredients___"))
-
-knitr::kable(tail(analysis))| - | ingredients___1 | -ingredients___2 | -ingredients___3 | -ingredients___4 | -ingredients___5 | -ingredients___6 | -ingredients___7 | -ingredients___8 | -
|---|---|---|---|---|---|---|---|---|
| 25 | -Checked | -Checked | -Unchecked | -Unchecked | -Unchecked | -Checked | -Unchecked | -Unchecked | -
| 26 | -Unchecked | -Unchecked | -Unchecked | -Unchecked | -Unchecked | -Unchecked | -Unchecked | -Unchecked | -
| 27 | -Unchecked | -Unchecked | -Unchecked | -Unchecked | -Unchecked | -Unchecked | -Unchecked | -Unchecked | -
| 28 | -Unchecked | -Unchecked | -Unchecked | -Unchecked | -Unchecked | -Unchecked | -Unchecked | -Unchecked | -
| 29 | -Unchecked | -Unchecked | -Unchecked | -Unchecked | -Unchecked | -Unchecked | -Unchecked | -Unchecked | -
| 30 | -Checked | -Checked | -Unchecked | -Unchecked | -Unchecked | -Unchecked | -Checked | -Unchecked | -
-
The make_binary_word() function combines responses from
-the individual variables into a single βwordβ that indicates which
-choices were selected. For example, if the first option from the NCI
-ingredient question, chips (i.e.,
-ingredients___1), was checked, the word created by
-make_binary_word() will begin with a; or if it was
-not checked, the word would start with _. If the second option,
-Yellow cheese (i.e., ingredients___2), was
-checked, the next letter will be a b; otherwise, a _
-will be used as a placeholder. Following this pattern, if somebody is
-not craving any of the eight nacho ingredients, the βwordβ will be eight
-underscores, one for each ingredient (i.e., ________). Conversely, if
-they are craving every ingredient, the βwordβ will be
-abcdefgh.
-patterns <- make_binary_word(analysis)
-janitor::tabyl(patterns)
-#> patterns n percent
-#> ________ 20 0.66666667
-#> ______gh 1 0.03333333
-#> a_c__f_h 1 0.03333333
-#> a_cdefgh 1 0.03333333
-#> ab____g_ 1 0.03333333
-#> ab___f__ 1 0.03333333
-#> ab___f_h 1 0.03333333
-#> ab__efgh 1 0.03333333
-#> ab_de_gh 1 0.03333333
-#> ab_defgh 1 0.03333333
-#> abcdef_h 1 0.03333333While the default lettering is somewhat helpful, using meaningful -(mnemonic) letters makes the binary words easier to understand. In this -case, the first letter for each choice can be used as a helpful -mnemonic.
-| Abbreviation | -Ingredient | -
|---|---|
| C | -Chips | -
| Y | -Yellow cheese | -
| O | -Orange cheese | -
| W | -White cheese | -
| M | -Meat | -
| B | -Beans | -
| T | -Tomatoes | -
| P | -Peppers | -
To use custom lettering, specify a vector of single-letter
-abbreviations and pass it to the the_labels argument. Be
-sure to include one unique abbreviation for each data frame column. For
-example:
-labels <- c("C", "Y", "O", "W", "M", "B", "T", "P")
-
-patterns <- make_binary_word(analysis, the_labels = labels)
-
-janitor::tabyl(patterns)
-#> patterns n percent
-#> CYOWMB_P 1 0.03333333
-#> CY_WMBTP 1 0.03333333
-#> CY_WM_TP 1 0.03333333
-#> CY__MBTP 1 0.03333333
-#> CY___B_P 1 0.03333333
-#> CY___B__ 1 0.03333333
-#> CY____T_ 1 0.03333333
-#> C_OWMBTP 1 0.03333333
-#> C_O__B_P 1 0.03333333
-#> ______TP 1 0.03333333
-#> ________ 20 0.66666667The summary table shows that 20 people did not provide information -about what ingredients they craved. The remaining people do not display -any recurring patterns, but many people craved chips and yellow cheese -together.
-vignettes/makeChooseAllTable.Rmd
- makeChooseAllTable.RmdREDCap exports a βchoose all that applyβ question into a series of -similarly-named, binary indicator variables (i.e., the variables are -equal to either βcheckedβ or βuncheckedβ). For example, the following -data represents a sample of responses to the Nacho Craving Index.
-
-redcap <- readRDS(file = "./redcap.rds")
-redcap %>%
- select(starts_with("ingredients___")) %>%
- head()
-#> ingredients___1 ingredients___2 ingredients___3 ingredients___4
-#> 1 Checked Checked Checked Checked
-#> 2 Checked Checked Unchecked Checked
-#> 3 Unchecked Unchecked Unchecked Unchecked
-#> 4 Unchecked Unchecked Unchecked Unchecked
-#> 5 Unchecked Unchecked Unchecked Unchecked
-#> 6 Unchecked Unchecked Unchecked Unchecked
-#> ingredients___5 ingredients___6 ingredients___7 ingredients___8
-#> 1 Checked Checked Unchecked Checked
-#> 2 Checked Unchecked Checked Checked
-#> 3 Unchecked Unchecked Unchecked Unchecked
-#> 4 Unchecked Unchecked Unchecked Unchecked
-#> 5 Unchecked Unchecked Unchecked Unchecked
-#> 6 Unchecked Unchecked Unchecked UncheckedIt is desirable to have a concise table showing how often each option -was chosen.
-See the Import All -Instruments from a REDCap Project and Importing from REDCap vignettes for -details/information.
-import_instruments()
-If you pass the make_choose_all_table() function, the
-name of a REDCap export, and the name of the choose all that apply
-question question in REDCap, it will produce a concise frequency
-count table.
-make_choose_all_table(redcap, "ingredients")
-#> # A tibble: 8 Γ 2
-#> What Count
-#> <chr> <dbl>
-#> 1 Chips 9
-#> 2 Yellow cheese 7
-#> 3 Orange cheese 3
-#> 4 White cheese 4
-#> 5 Meat 5
-#> 6 Beans 7
-#> 7 Tomatoes 6
-#> 8 Peppers 8Similar to the make_choose_one_table() function, we can
-use this function inside an analysis pipeline. We can add the
-kable() call to make the table publication quality.
-redcap %>%
- make_choose_all_table("ingredients") %>%
- knitr::kable()| What | -Count | -
|---|---|
| Chips | -9 | -
| Yellow cheese | -7 | -
| Orange cheese | -3 | -
| White cheese | -4 | -
| Meat | -5 | -
| Beans | -7 | -
| Tomatoes | -6 | -
| Peppers | -8 | -
If you export data using the point-and-click tools built into REDCap
-you end up with two files, one contains R code the other data. When you
-run the code you end up with a dataset called data which
-contains two copies of some of the information. For example, if you
-download the Nacho Craving Index you will see the ingredients variables,
-showing what ingredients people are craving, and a second copy of the
-variables that have .factor tagged to the end of the names.
-The factor versions do not have the variable labels. So you will need to
-subset the data to drop them. The example below shows the process. Note
-we have copied the data data frame to have a more
-meaningful name.
-# This is the data produced by exporting using point-and-click REDCap export.
-manual_export <- data
-
-manual_export |>
- select(starts_with("ingredient")) |> # get all the ingredient variables
- select(-ends_with(".factor")) |> # drop the factor version of the ingredient variables
- make_choose_all_table("ingredient") # make the tablevignettes/makeChooseOneTable.Rmd
- makeChooseOneTable.RmdIt is often desirable to print variable labels above a summary table -that shows the count of factor labels. The labels exported on choose -all that apply questions, including the question and whichever -response was chosen. This redundancy is often unwanted, and the results -are not presented professionally.
-For example, in the Nacho Craving Index data, the first ingredient is
-βChipsβ. We see how R presents this information by simply printing the
-components of the ingredients___1 column.
-redcap <- readRDS(file = "./redcap.rds")
-redcap$ingredients___1
-# What ingredients do you currently crave?: Chips
-# [1] Checked Checked Unchecked Unchecked Unchecked Unchecked Checked
-# [8] Unchecked Unchecked Unchecked Unchecked Unchecked Checked Unchecked
-# [15] Unchecked Checked Unchecked Unchecked Checked Unchecked Unchecked
-# [22] Unchecked Checked Unchecked Checked Unchecked Unchecked Unchecked
-# [29] Unchecked Checked
-# attr(,"redcapLabels")
-# [1] Unchecked Checked
-# attr(,"redcapLevels")
-# [1] 0 1
-# Levels: Unchecked CheckedAs we can see, this information is quite ugly, so we want to tabulate
-the results instead. However, if we use the simple table()
-function to clean up this information, we lose the original question and
-the answer label for ingredients___1.
-table(redcap$ingredients___1)
-#
-# Unchecked Checked
-# 21 9We no longer know what the question was or which βselect allβ option -this information represents.
-See the Import All -Instruments from a REDCap Project and Importing from REDCap vignettes for -details/information.
-The make_choose_one_table() function can be used with a
-factor variable to tabulate the response while preserving the
-question and checked option context.
-make_choose_one_table(redcap$ingredients___1)
-# What ingredients do you currently crave?: Chips
-# Response n percent
-# Unchecked 21 70%
-# Checked 9 30%Further, this output can be molded into a publication-ready table -with a single additional function call.
-
-make_choose_one_table(redcap$ingredients___1) %>%
- knitr::kable()What ingredients do you currently crave?: Chips
-| Response | -n | -percent | -
|---|---|---|
| Unchecked | -21 | -70% | -
| Checked | -9 | -30% | -
The subset option, if set to TRUE, will
-cause the function to remove the labelβs text and only show the response
-option (i.e., not repeat the βWhat ingredients do you currently crave?β
-question).
-make_choose_one_table(
- redcap$ingredients___2,
- subset = TRUE
-) %>%
- knitr::kable()Yellow cheese
-| Response | -n | -percent | -
|---|---|---|
| Unchecked | -23 | -77% | -
| Checked | -7 | -23% | -
This function can also be used in an analysis pipeline with a data -frame name and the name of the factor inside that data frame. For -example:
-
-redcap %>%
- make_choose_one_table(ingredients___3) %>%
- knitr::kable() What ingredients do you currently crave?: Orange cheese
-| Response | -n | -percent | -
|---|---|---|
| Unchecked | -27 | -90% | -
| Checked | -3 | -10% | -
REDCap exports longitudinal projects with one record (a line of data)
-per assessment (typically 1 line per day). This works well when every
-instrument/questionnaire is given at every assessment. Still, for
-projects with different instruments/questionnaires given on different
-days, REDCap exports empty values (represented by the value
-NA in R).
--Example: In the Nachos for Anxiety project, three -instruments were used; they each had a different administration -schedule. Subjectsβ anxiety was assessed at baseline with the -Generalized Anxiety Disorder 7-item (GAD-7) scale. Every day, it was -assessed with the Hamilton Anxiety Scale (HAM-A), but the Nacho Craving -Index was administered only at the baseline and at the end of the study -(see the figure below for clarification).
-
The instruments that are not assessed every day appear as entirely -blank questionnaires when the data is exported. For example, values from -the NCI instrument are shown as missing for Day 1, Day 2, and Day 3 -(because it was not administered during those visits).
-In R, this data is displayed as
-
-redcap <- readRDS(file = "./redcap_nacho_anxiety.rds")
-
-redcap %>%
- select(
- # Select these two columns
- record_id, redcap_event_name,
- # And also select all columns between "nachos" and "nci_complete"
- nachos:nci_complete
- ) %>%
- # Make the table pretty
- knitr::kable()| record_id | -redcap_event_name | -nachos | -treat | -treating | -othercondition | -last | -traveled | -miles | -now | -strong | -ingredients___1 | -ingredients___2 | -ingredients___3 | -ingredients___4 | -ingredients___5 | -ingredients___6 | -ingredients___7 | -ingredients___8 | -cheese | -crunch | -bean | -guacamole | -jalapeno | -meat | -life | -nci_complete | -
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | -baseline_arm_1 | -Yes | -TRUE | -Other | -Anxiety | -I ate nachos in the last year. | -Yes | -3115 | -Yes | -74 | -Checked | -Checked | -Unchecked | -Checked | -Checked | -Checked | -Checked | -Checked | -5 Love it | -5 Love it | -5 Love it | -5 Love it | -5 Love it | -5 Love it | -They helped me cure my hunger. | -Complete | -
| 1 | -day_1_arm_1 | -NA | -NA | -NA | -NA | -NA | -NA | -NA | -NA | -NA | -NA | -NA | -NA | -NA | -NA | -NA | -NA | -NA | -NA | -NA | -NA | -NA | -NA | -NA | -NA | -NA | -
| 1 | -day_2_arm_1 | -NA | -NA | -NA | -NA | -NA | -NA | -NA | -NA | -NA | -NA | -NA | -NA | -NA | -NA | -NA | -NA | -NA | -NA | -NA | -NA | -NA | -NA | -NA | -NA | -NA | -
| 1 | -day_3_arm_1 | -NA | -NA | -NA | -NA | -NA | -NA | -NA | -NA | -NA | -NA | -NA | -NA | -NA | -NA | -NA | -NA | -NA | -NA | -NA | -NA | -NA | -NA | -NA | -NA | -NA | -
| 1 | -end_arm_1 | -Yes | -TRUE | -Other | -Anxiety | -I am currently eating nachos. | -Yes | -3115 | -Yes | -90 | -Checked | -Checked | -Checked | -Checked | -Checked | -Checked | -Checked | -Checked | -5 Love it | -5 Love it | -5 Love it | -5 Love it | -5 Love it | -5 Love it | -They make me feel happy. | -Complete | -
It is often helpful to make a different data table that has the -values for each questionnaire without the blank records.
-See the Import All -Instruments from a REDCap Project and Importing from REDCap vignettes for -details/information.
-Pass the make_instrument() function to the name of a
-dataset and the names of the first and last variables in an instrument,
-and it will return a table that has the non-empty records for the
-instrument. For example, to extract the enrollment/consent
-instrument:
-make_instrument(redcap, "concented", "enrollment_complete") %>%
- knitr::kable()| record_id | -redcap_event_name | -concented | -enrollment_complete | -
|---|---|---|---|
| 1 | -baseline_arm_1 | -Yes | -Complete | -
To extract nacho craving information:
-
-make_instrument(redcap, "nachos", "nci_complete") %>%
- knitr::kable()| - | record_id | -redcap_event_name | -nachos | -treat | -treating | -othercondition | -last | -traveled | -miles | -now | -strong | -ingredients___1 | -ingredients___2 | -ingredients___3 | -ingredients___4 | -ingredients___5 | -ingredients___6 | -ingredients___7 | -ingredients___8 | -cheese | -crunch | -bean | -guacamole | -jalapeno | -meat | -life | -nci_complete | -
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | -1 | -baseline_arm_1 | -Yes | -TRUE | -Other | -Anxiety | -I ate nachos in the last year. | -Yes | -3115 | -Yes | -74 | -Checked | -Checked | -Unchecked | -Checked | -Checked | -Checked | -Checked | -Checked | -5 Love it | -5 Love it | -5 Love it | -5 Love it | -5 Love it | -5 Love it | -They helped me cure my hunger. | -Complete | -
| 5 | -1 | -end_arm_1 | -Yes | -TRUE | -Other | -Anxiety | -I am currently eating nachos. | -Yes | -3115 | -Yes | -90 | -Checked | -Checked | -Checked | -Checked | -Checked | -Checked | -Checked | -Checked | -5 Love it | -5 Love it | -5 Love it | -5 Love it | -5 Love it | -5 Love it | -They make me feel happy. | -Complete | -
To make an analysis dataset containing the NCI values -without the subject ID and the event name:
-
-make_instrument(
- redcap,
- "nachos", "nci_complete",
- drop_which_when = TRUE
-) %>%
- knitr::kable()| - | nachos | -treat | -treating | -othercondition | -last | -traveled | -miles | -now | -strong | -ingredients___1 | -ingredients___2 | -ingredients___3 | -ingredients___4 | -ingredients___5 | -ingredients___6 | -ingredients___7 | -ingredients___8 | -cheese | -crunch | -bean | -guacamole | -jalapeno | -meat | -life | -nci_complete | -
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1 | -Yes | -TRUE | -Other | -Anxiety | -I ate nachos in the last year. | -Yes | -3115 | -Yes | -74 | -Checked | -Checked | -Unchecked | -Checked | -Checked | -Checked | -Checked | -Checked | -5 Love it | -5 Love it | -5 Love it | -5 Love it | -5 Love it | -5 Love it | -They helped me cure my hunger. | -Complete | -
| 5 | -Yes | -TRUE | -Other | -Anxiety | -I am currently eating nachos. | -Yes | -3115 | -Yes | -90 | -Checked | -Checked | -Checked | -Checked | -Checked | -Checked | -Checked | -Checked | -5 Love it | -5 Love it | -5 Love it | -5 Love it | -5 Love it | -5 Love it | -They make me feel happy. | -Complete | -
While most people use the βData Exports, Reports and Statsβ -Application built into REDCap, another handy method to get data out of -REDCap is an API request. An API allows one program to request data from -another program. For example, an add-on package in R can request data -from your instance of REDCap. Obviously, an R package can not -type your user name and password. Instead, you will store an -API token, a password, on your machine and then ask R to look up that -token and pass it to REDCap whenever you want data.
-We have used two R packages to access our REDCap
-projects,redcapAPI and REDCapR. Unfortunately,
-redcapAPI is no longer being actively developed, and we
-have run into problems with it. It had the lovely benefit of exporting
-variables, basically using the same variable names as you see in REDCap,
-then tagging the variables with the βlabelsβ subjects viewed when
-completing the forms.
that people taking REDCap surveys or viewing other forms see.
-We have taken the labeling functionality and added it in -tidyREDCap.
-If your REDCap project has API access enabled, you will see it in the -applications on the left side of the screen.
-
If you donβt see that option, talk to your project leader or the -REDCap system administrator.
-When you click the link you will be given the option to create an API -Token for this project.
-Once you have that token created, you can copy and paste it somewhere -safe.
-Leaders in the REDCap community have developed techniques for safely -storing your REDCap API keys. Ask your REDCap systems administrators how -they prefer you store API keys on your βlocal machineβ.
-The functions that allow you to export data need you to give them -your API token. Remember, this is the same information as your username -and password. NEVER type that directly in your code. -That is if your REDCap API key is β1A2B3CXXYYZZOOMMGOSHNOOOOX1Y2Z3β do -NOT do this:
-
-# Do not type your API token directly into your code
-tidyREDCap::import_instruments(
- "https://redcap.miami.edu/api/",
- "1A2B3CXXYYZZOOMMGOSHNOOOOX1Y2Z3" # This is BAD!
-)If you do this, anybody who gets a copy of your code will be able to -access your REDCap project. Also, whenever your run this line of code, -the API token will be saved into your R history files.
-You can save your API keys into a βhiddenβ file containing code that
-runs when you start R. That file is called you β.Renvironβ. It can be a
-bit of a pain to find. So your best plan is to install the
-usethis package, which contains helper functions, including
-a function to find this file. If you use the RStudio interface, you can
-add it using the Packages window pane or run these lines in the console
-once.
-install.packages("remotes")
-remotes::install_cran("usethis")When it comes time to add packages to your copy of R, the
-install_cran() function in the remotes package
-is superior to the usual install.packages() function
-because it will first check to see if you already have the latest
-version before bothering to download and install.
After installing usethis you can access your β.Renvironβ
-file by typing this in your console.
-usethis::edit_r_environ()It will cause the file to open.
-Create a name for your API key and add a like like this to your -.Renviron file:
-nacho_anxiety_key="1A2B3CXXYYZZOOMMGOSHNOOOOX1Y2Z3"
-After adding the line, remember to save the file and completely -restart R/RStudio.
-Once R restarts, you can access the key like this:
-
-tidyREDCap::import_instruments(
- "https://redcap.miami.edu/api/",
- Sys.getenv("nacho_anxiety_key")
-)If you want to use the redcapAPI or the REDCapR packages directly you -can use the same trickery to pass your API key to their functions. For -example:
-
-rcon <- redcapAPI::redcapConnection(
- url = 'https://redcap.miami.edu/api/',
- token = Sys.getenv("nacho_anxiety_key")
-)
-
-redcap <- redcapAPI::exportRecords(rcon)This includes a call to Sys.getenv() to grab the key. To
-learn more about working with APIs, look here.
If you are curious, when we made these help files, we saved the data
-using the saveRDS() function.
-rcon <- redcapAPI::redcapConnection(
- url = 'https://redcap.miami.edu/api/',
- token = Sys.getenv("nacho_anxiety_key")
-)
-
-redcap <- redcapAPI::exportRecords(rcon)
-
-saveRDS(redcap, file = "redcap.rds")-
If somebody gets access to the files on your machine, they could find
-and read your .Renviron file. A more secure option is to use the r
-keyring package. It will store an encrypted copy of your
-API key in your machineβs credential store (i.e., the βkeychainβ on
-macOS, the Credential Store on Windows, etc.). Consider using it. If you
-use it and your machine is stolen, it will buy you more time to find an
-internet connection, log into REDCap and change your API tokens (before
-the thief can access your data).
tidyREDCap is an R package with functions for processing REDCap data.
-βREDCapβ (Research Electronic Data CAPture; https://projectredcap.org) is a web-enabled application for building and managing surveys and databases developed at Vanderbilt University.
-π₯ NEW in Version 1.1 π₯ import_instruments() includes the repeat number for repeated instruments/forms/questionnaires.
import_instruments() will use an API call to load every instrument/questionnaire into its own R dataset. If the REDCap project is longitudinal or has repeated instruments, the function will remove blank records.
After loading data into R using RStudio with the import_instruments() function, you can see both the variable name and the text that appears to users of REDCap. All you need to do is click on the datasetβs name in the Environment tab or use the View() function. The column headings will include both the variable name and the Field Label from REDCap.
π₯ NEW in Version 1.1 π₯ Functions coming from packages outside of tidyREDCap may not understand what to do with labeled variables. So, tidyREDCap includes a new drop_labels() function that will allow you to strip the labels before using functions that want unlabeled data.
make_choose_one_table(): print a janitor::tabyl() style table with a variable label. This function lets you print one choice from a choose all that apply question.REDCap exports the responses to a choose all that apply question into many similarly named questions. tidyREDCap helps summarize the responses with two functions:
-make_binary_word(): converts all the responses into a single descriptive βwordβmake_choose_all_table(): converts all the responses into a single summary tableProjects that have repeated assessments with different questionnaires/instruments export with holes in the CSV. tidyREDCap will parse the export and create tables for any of the questionnaires/instruments:
-make_instrument(): makes a tibble for a questionnaire/instrumentMain Page: https://raymondbalise.github.io/tidyREDCap/
User Guides: https://raymondbalise.github.io/tidyREDCap/articles/
-Development Site: https://github.com/RaymondBalise/tidyREDCap
You can get the latest official release of tidyREDCap from CRAN.
-install.packages("tidyREDCap")
-Run these two lines of code to install tidyREDCap from GitHub (this requires RTools for Windows or Xcode for Mac to be installed on your computer):
-if (!requireNamespace("devtools")) install.packages("devtools")
-devtools::install_github("RaymondBalise/tidyREDCap")
-make_yes_no() function to convert βcheckedβ or βyesβ-like answers to βYesβ and other answers to βNo or Unknownβ.make_yes_no_unknown() function to convert βcheckedβ or βyesβ-like answers to βYesββ, unchecked orβnoβ-like answers to βNoβ and other answers to βUnknownβ.We are currently in active development of tidyREDCap. If one of our functions does not work the way that you expect, or if one of our functions is broken, please submit an issue ticket (using a reproducible example) to our issues page. If you have a cool idea for our next new function, also submit an issue ticket. If you are an R developer and want so contribute to this package, please submit an issue ticket or a pull request.
-The development of this package was supported by:
-NEWS.md
- make_yes_no() function to convert βcheckedβ or βyesβ-like answers to βYesβ and other answers to βNo or Unknownβ.make_yes_no_unknown() function to convert βcheckedβ or βyesβ-like answers to βYesββ, unchecked orβnoβ-like answers to βNoβ and other answers to βUnknownβ.make_choose_all_table() now works with api or manual/point-and-click exports. ## Added S3 methods so dplyr (and friends) can work with labelled objectsdrop_labels() function for datasets. Used to deal with packages/functions that donβt want labeled variables (i.e.Β dplyr::pivot_longer() and skimr::skim()
-record_id = and first_record_id = for custom record_id fields in import_instruments()
-import_instruments()
-import_instruments() runsimport_instruments() loading repeated instruments (the first instrument in a project was badly messed up)import_instruments() function imports all instruments with a single commandmake_choose_one_table() no longer requires factorsmake_choose_all_table() now works with β1β vs β0β indicator variablesimport_instruments() function to import all instruments; currently uses the REDCapR package as the APImake_choose_all_table() with repeating instruments showing NA countssummarise_all() functionmutate_if and mutate_all from make_choose_all_table()
-import_instruments() functionmake_instrument_auto() functionrlang bug in make_choose_all_table(); see https://github.com/RaymondBalise/tidyREDCap/pull/13
-make_choose_all_table() functionmake_instrument() functionmake_choose_one_table() functionCuts html tags from a variable. Used to clean labels
-dropTags(x)a string
a string
-There is a reported issues with joins on data (without a reprex) -that seem to be caused by the labels. As a possible solution this can be -used to drop labels.
-drop_label(df, x)the name of the data frame
the quoted name of the variable
df
-There is an issue with the function we are using to add column -labels. If you run into problems processing the labels.
-drop_labels(df)The data frame with column labels that you want to drop
df without column labels
-if (FALSE) {
-demographics |>
- drop_labels() |>
- skimr::skim()
-}
-R/make_choose_all_table.R
- getLabel2.RdGet a variable's label from a data frame and variable
-getLabel2(data, aVariable)The name of the data set
The name of the variable
A variable's response label without the repeated text from of a -choose all that apply question
-R/import_instruments.R
- import_instruments.RdThis function takes the url and key for a REDCap -project and returns a table for each instrument/form in the project.
-import_instruments(
- url,
- token,
- drop_blank = TRUE,
- record_id = "record_id",
- first_record_id = 1,
- envir = .GlobalEnv
-)The API URL for your the instance of REDCap
The API security token
Drop records that have no data. TRUE by default.
Name of record_id variable (if it was changed in REDCap).
A value of the custom record_id variable (if
-changed in REDCap). To improve the speed of the import, tidyREDCap pulls
-in a single record twice. By default if uses the first record. If you
-have a custom record_id variable and if its the first record identifier
-is not 1, specify a record identifier value here. For example if you
-are using dude_id instead of record_id and dude_id has a value of
-"first dude" for one of its records this argument would be
-first_record_id = "first dude".
The name of the environment where the tables should be saved.
one data.frame for each instrument/form in a REDCap project. By
-default the datasets are saved into the global environment.
if (FALSE) {
-import_instruments(
- "https://redcap.miami.edu/api/",
- Sys.getenv("test_API_key")
-)
-}
-
- All functions- - |
- |
|---|---|
| - - | -Drop the label from a variable |
-
| - - | -Drop all the labels from a variable |
-
| - - | -Import all instruments into individual R tables |
-
| - - | -Convert a "choose all that apply" Question Into a Binary Word |
-
| - - | -Count The Responses to a Choose All That Apply Question |
-
| - - | -Make a frequency table for a categorical variable |
-
| - - | -Extract an Instrument from an REDCap Export |
-
| - - | -Extract an Instrument from an REDCap Export without specifying Variables |
-
| - - | -make_yes_no |
-
| - - | -make_yes_no_unknown |
-
R/make_binary_word.R
- make_binary_word.RdThis function takes a data frame holding binary variables with -values corresponding to a dummy-coded "choose all that apply" question. -It can be used for any binary word problem.
-make_binary_word(df, yes_value = "Checked", the_labels = letters)A data frame with the variables corresponding to binary indicators -(the dummy coded variables) for a "choose all that apply" question.
A character string that corresponds to choosing "yes"
-in the binary variables of df. Defaults to the REDCap "Checked" option.
A character vector of single letters holding the letters -used to make the binary word. See the article/vignette called "Make -Binary Word" for an example: -https://raymondbalise.github.io/tidyREDCap/articles/makeBinaryWord.html.
A character vector with length equal to the rows of df, including
-one letter or underscore for each column of df. For instance, if df
has one column for each of the eight options of the Nacho Craving Index
-example instrument (https://libguides.du.edu/c.php?g=948419&p=6839916),
-with a row containing the values "Chips" (checked), "Yellow cheese"
-(unchecked), "Orange cheese" (checked), "White cheese" (checked), "Meat"
-(checked), "Beans" (unchecked), "Tomatoes" (unchecked) and "Peppers"
-(checked), then the character string corresponding to that row will be
-"a_cde__h". The underscores represent that the options for "Yellow
-cheese", "Beans", and "Tomatoes" were left unchecked.
R/make_choose_all_table.R
- make_choose_all_table.RdThis will tally the number of responses on a choose all that -apply question. This function extracts the option name from the variable -labels. So the data set needs to be labeled. See -the Make a 'Choose All' Table vignette -for help.
-make_choose_all_table(df, variable)The name of the data set (it needs labels)
The name of the REDCap variable
A variable's response label without the choose all the question
-R/make_choose_one_table.R
- make_choose_one_table.RdPass this function either 1) a labeled factor or 2)
-a data frame and also
-a factor in the frame, and it will return a janitor-style table.
-Use subset = TRUE if you are making a report on a variable that is part of
-a choose all that apply question.
make_choose_one_table(arg1, arg2, subset = FALSE)data frame that has a factor or a factor name
if arg1 is a data frame, this is a factor name
can be equal to TRUE/FALSE. This option removes extra variable -name text from the label. This option is useful for choose all that -apply questions.
a table
-This function takes a data frame and the names of the first and -last variables in an instrumnt and returns a data frame with the instrument.
-make_instrument(
- df,
- first_var,
- last_var,
- drop_which_when = FALSE,
- record_id = "record_id"
-)A data frame with the instrument
The name of the first variable in an instrument
The name of the last variable in an instrument
Drop the record_id and redcap_event_name variables
Name of record_id variable (if it was changed in REDCap)
A data frame that has an instrument (with at least one not NA value)
-R/make_instrument_auto.R
- make_instrument_auto.RdThis function takes a data frame holding REDCap data, -checks if it is a longitudinal study, and returns records that have values.
-make_instrument_auto(df, drop_which_when = FALSE, record_id = "record_id")A data frame with the instrument
Drop the record_id and redcap_event_name variables
Name of record_id variable (if it was changed in REDCap)
A data frame that has an instrument (with at least one not NA value).
-Convert a "Yes-No", "True-False" or "Checkboxes (Multiple
-Answers)" question in REDCap to a factor holding "Yes" or
-"No or Unknown". Technically "yes" or "checked" (ignoring case), 1 or
-TRUE responses are converted to "Yes" and all other values to
-"No or Unknown". Also see make_yes_no_unknown().
make_yes_no(x)x variable to be converted to hold "Yes" or "No or Unknown"
a factor with "Yes" or "No or Unknown"
-Convert a "Yes-No", "True-False" or "Checkboxes (Multiple
-Answers)" question in REDCap to a factor holding "No" or
-"Yes" or "Unknown". Technically "yes" or "checked" (ignoring case), 1 or
-TRUE responses are converted to "Yes". "No" or "unchecked" (ignoring
-case), 0 or FALSE are converted to "No". All other values are set to
-"Unknown". Also see make_yes_no().
make_yes_no_unknown(x)variable to be converted to hold "No", "Yes", or Unknown"
a factor with "No", "Yes", or Unknown"
-See magrittr::%>% for details.
lhs %>% rhsMake a labeled janitor table from a single variable
-taybull(variable, subset = FALSE)a factor to report on
parse off extra variable if used with a choose all question
a table
-Make a labeled janitor table from a dataset and variable
-taybull2(data, aVariable, subset = FALSE)a dataframe that has the factor to report on
a factor to report on
TRUE/FALSE used to remove the repeated text from of a -choose all that apply question
a table
-Figure 1
The same functionality should help deal with instruments that are potentially given repeatedly. Common examples include asking participants to fill out a form describing medical conditions for all their siblings or asking them to fill out a form for each side effect they experience while using a drug. In these cases, each participant may have zero or many records. Again, creating a table with all the records for these βrepeatedβ instruments would be good. @@ -61,10 +61,10 @@ The `import_instruments()` function can be given a URL and token for a REDCap pr After running the above code we get four tables from the REDCap project. - + Notice that each repeat of the HAM-A is its own record. - + If a person has only done the baseline assessment they will only have one record. diff --git a/vignettes/makeBinaryWord.Rmd b/vignettes/makeBinaryWord.Rmd index f52be82..28add45 100644 --- a/vignettes/makeBinaryWord.Rmd +++ b/vignettes/makeBinaryWord.Rmd @@ -28,7 +28,7 @@ REDCap exports a "choose all that apply" question into a series of similarly-nam > **Example:** In the Nacho Craving Index (NCI), respondents can indicate which of eight ingredients they are currently craving (i.e., Chips, Yellow cheese, Orange cheese, White cheese, Meat, Beans, Tomatoes, Peppers). These are exported into variables with names like `ingredients___1`, `ingredients___2`, etc. -In REDCap, it is simple to get a summary of those individual variables by using the "Data Exports, Reports, and Stats" application within the REDCap interface and selecting "Stats & Charts". Once the data is in R, simple tables can be produced with the `table()` function, or beautiful tables can be created with the `tabyl()` and `adorn_pct_formatting()` functions from the `janitor` package. However, from these univariate tables, it is impossible to judge which patterns of answers are marked together. In the above example, using the univariate tables, it is difficult to tell what percentage of people are craving both chips and yellow cheese. +In REDCap, it is simple to get a summary of those individual variables by using the "Data Exports, Reports, and Stats" application within the REDCap interface and selecting "Stats & Charts". Once the data is in R, simple tables can be produced with the `table()` function, or beautiful tables can be created with the `tabyl()` and `adorn_pct_formatting()` functions from the [`janitor`](https://sfirke.github.io/janitor/index.html) package. However, from these univariate tables, it is impossible to judge which patterns of answers are marked together. In the above example, using the univariate tables, it is difficult to tell what percentage of people are craving both chips and yellow cheese. ```{r univariate, warning=FALSE} redcap <- readRDS(file = "./redcap.rds") @@ -46,7 +46,7 @@ janitor::tabyl(redcap$ingredients___2) %>% ``` ## Aside: Loading REDCap Data into R -See the [Import All Instruments from a REDCap Project](../doc/importInstruments.html) and [Importing from REDCap](../doc/useAPI.html) vignettes for details/information. +See the [Import All Instruments from a REDCap Project](./import_instruments.html) and [Importing from REDCap](./useAPI.html) vignettes for details/information. # Make Analysis Data diff --git a/vignettes/makeChooseAllTable.Rmd b/vignettes/makeChooseAllTable.Rmd index 703a5c2..64292f8 100644 --- a/vignettes/makeChooseAllTable.Rmd +++ b/vignettes/makeChooseAllTable.Rmd @@ -34,7 +34,7 @@ redcap %>% It is desirable to have a concise table showing how often each option was chosen. ## Aside: Loading REDCap Data into R -See the [Import All Instruments from a REDCap Project](../doc/importInstruments.html) and [Importing from REDCap](../doc/useAPI.html) vignettes for details/information. +See the [Import All Instruments from a REDCap Project](./import_instruments.html) and [Importing from REDCap](./useAPI.html) vignettes for details/information. # The Solution diff --git a/vignettes/makeChooseOneTable.Rmd b/vignettes/makeChooseOneTable.Rmd index d6b4729..303dc37 100644 --- a/vignettes/makeChooseOneTable.Rmd +++ b/vignettes/makeChooseOneTable.Rmd @@ -37,7 +37,7 @@ table(redcap$ingredients___1) We no longer know what the question was or which "select all" option this information represents. ## Aside: Loading REDCap Data into R -See the [Import All Instruments from a REDCap Project](../doc/importInstruments.html) and [Importing from REDCap](../doc/useAPI.html) vignettes for details/information. +See the [Import All Instruments from a REDCap Project](./import_instruments.html) and [Importing from REDCap](./useAPI.html) vignettes for details/information. # The Solution The `make_choose_one_table()` function can be used with a factor variable to tabulate the response *while preserving the question and checked option context*. diff --git a/vignettes/makeInstrument.Rmd b/vignettes/makeInstrument.Rmd index 2e91ab3..49a0e64 100644 --- a/vignettes/makeInstrument.Rmd +++ b/vignettes/makeInstrument.Rmd @@ -27,7 +27,7 @@ library(dplyr) REDCap exports longitudinal projects with one record (a line of data) per assessment (typically 1 line per day). This works well when every instrument/questionnaire is given at every assessment. Still, for projects with different instruments/questionnaires given on different days, REDCap exports empty values (represented by the value `NA` in R). > **Example:** In the Nachos for Anxiety project, three instruments were used; they each had a different administration schedule. Subjects' anxiety was assessed at baseline with the Generalized Anxiety Disorder 7-item (GAD-7) scale. Every day, it was assessed with the Hamilton Anxiety Scale (HAM-A), but the Nacho Craving Index was administered only at the baseline and at the end of the study (see the figure below for clarification). - + The instruments that are not assessed every day appear as entirely blank questionnaires when the data is exported. For example, values from the NCI instrument are shown as missing for Day 1, Day 2, and Day 3 (because it was not administered during those visits). @@ -49,7 +49,7 @@ redcap %>% It is often helpful to make a different data table that has the values for each questionnaire without the blank records. ## Aside: Loading REDCap Data into R -See the [Import All Instruments from a REDCap Project](../doc/importInstruments.html) and [Importing from REDCap](../doc/useAPI.html) vignettes for details/information. +See the [Import All Instruments from a REDCap Project](./import_instruments.html) and [Importing from REDCap](./useAPI.html) vignettes for details/information. # The Solution diff --git a/vignettes/useAPI.Rmd b/vignettes/useAPI.Rmd index 401e1f6..86545a8 100644 --- a/vignettes/useAPI.Rmd +++ b/vignettes/useAPI.Rmd @@ -23,15 +23,13 @@ While most people use the "Data Exports, Reports and Stats" Application built in We have used two R packages to access our REDCap projects,`redcapAPI` and `REDCapR`. Unfortunately, `redcapAPI` is no longer being actively developed, and we have run into problems with it. It had the lovely benefit of exporting variables, basically using the same variable names as you see in REDCap, then tagging the variables with the "labels" subjects viewed when completing the forms. -that people taking REDCap surveys or viewing other forms see. - We have taken the labeling functionality and added it in tidyREDCap. ### Getting an API Token If your REDCap project has API access enabled, you will see it in the applications on the left side of the screen. - + If you don't see that option, talk to your project leader or the REDCap system administrator. @@ -104,7 +102,7 @@ rcon <- redcapAPI::redcapConnection( redcap <- redcapAPI::exportRecords(rcon) ``` -This includes a call to `Sys.getenv()` to grab the key. To learn more about working with APIs, look [here](https://daattali.gitbooks.io/stat545-ubc-github-io/bit003_api-key-env-var.html). +This includes a call to `Sys.getenv()` to grab the key. To learn more about working with APIs, look [here](https://daattali.gitbooks.io/stat545-ubc-github-io/content/bit003_api-key-env-var.html). If you are curious, when we made these help files, we saved the data using the `saveRDS()` function. @@ -124,4 +122,4 @@ saveRDS(redcap, file = "redcap.rds") ### Even Better Options -If somebody gets access to the files on your machine, they could find and read your .Renviron file. A more secure option is to use the r `keyring` package. It will store an encrypted copy of your API key in your machine's credential store (i.e., the "keychain" on macOS, the Credential Store on Windows, etc.). Consider using it. If you use it and your machine is stolen, it will buy you more time to find an internet connection, log into REDCap and change your API tokens (before the thief can access your data). \ No newline at end of file +If somebody gets access to the files on your machine, they could find and read your .Renviron file. A more secure option is to use the r `keyring` package. It will store an encrypted copy of your API key in your machine's credential store (i.e., the "keychain" on macOS, the Credential Store on Windows, etc.). Consider using it. If you use it and your machine is stolen, it will buy you more time to find an internet connection, log into REDCap and change your API tokens (before the thief can access your data).