Skip to content

Commit

Permalink
Merge pull request #301 from OuhscBbmc/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
wibeasley authored Mar 14, 2020
2 parents 6c4e6b5 + 072ae87 commit 9f9139e
Show file tree
Hide file tree
Showing 46 changed files with 1,310 additions and 598 deletions.
2 changes: 2 additions & 0 deletions .Rbuildignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@
^doc$
^.*\.Rproj$
^\.Rproj\.user$
^\.github$
^\.gitignore$
^\.travis.yml$
^\.vscode$
^cran-comments\.md$
README.html$

Expand Down
30 changes: 30 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"cSpell.words": [
"Bbmc",
"Munge",
"Ouhsc",
"anova",
"dataset",
"datasets",
"devtools",
"dplyr",
"glyphicon",
"gsub",
"httr",
"kable",
"knitr",
"magrittr",
"odbc",
"oneshot",
"rcon",
"readr",
"rmarkdown",
"sessioninfo",
"smallint",
"testit",
"tibble",
"tidyr",
"tidyverse",
"varchar"
]
}
33 changes: 16 additions & 17 deletions DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Description: Encapsulates functions to streamline calls from R to the REDCap
University. The Application Programming Interface (API) offers an avenue
to access and modify data programmatically, improving the capacity for
literate and reproducible programming.
Version: 0.10.2.9005
Version: 0.10.2.9006
Authors@R: c(person("Will", "Beasley", role = c("aut", "cre"), email =
"[email protected]", comment = c(ORCID = "0000-0002-5613-5006")),
person("David", "Bard", role = "ctb"),
Expand All @@ -25,28 +25,27 @@ BugReports: https://github.com/OuhscBbmc/REDCapR/issues
Depends:
R(>= 3.0.0)
Imports:
checkmate (>= 1.8.4),
dplyr (>= 0.5.0),
httr (>= 1.3.0),
magrittr,
checkmate (>= 2.0),
dplyr (>= 0.8.0),
httr (>= 1.4.0),
magrittr (>= 1.5),
methods,
readr (>= 1.3.1),
rlang,
tibble (>= 1.4.0),
tidyr (>= 0.7.0)
rlang (>= 0.4),
tibble (>= 2.0),
tidyr (>= 1.0)
Suggests:
covr,
DBI (>= 0.7.0),
devtools (>= 1.13.0),
kableExtra,
knitr (>= 1.18.0),
covr (>= 3.4),
DBI (>= 1.1),
kableExtra (>= 1.0),
knitr (>= 1.18),
odbc (>= 1.1.1),
rmarkdown,
sessioninfo,
testthat (>= 0.9)
rmarkdown (>= 2.0),
sessioninfo (>= 1.1.1),
testthat (>= 2.0)
License: GPL-2
LazyData: TRUE
VignetteBuilder: knitr
Encoding: UTF-8
RoxygenNote: 7.0.2
RoxygenNote: 7.1.0
Roxygen: list(markdown = TRUE)
1 change: 1 addition & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export(redcap_next_free_record_name)
export(redcap_project)
export(redcap_read)
export(redcap_read_oneshot)
export(redcap_survey_link_export_oneshot)
export(redcap_upload_file_oneshot)
export(redcap_users_export)
export(redcap_variables)
Expand Down
4 changes: 3 additions & 1 deletion NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ Version 0.11 (Released ?)

* [`reader::type_convert()`](https://readr.tidyverse.org/reference/type_convert.html) is used *after* all the batches are stacked on top of each other. This way, batches cannot have incompatible data types as they're combined. (#257; thanks @isaactpetersen #245) Consequently, the `guess_max` parameter in `redcap_read()` no longer serves a purpose, and has been soft-deprecated. (#267)

* [`redcap_metadata_write()`](https://readr.tidyverse.org/reference/redcap_metadata_write.html) writes to the project's metadata. (#274, @felixetorres)
* [`redcap_metadata_write()`](https://ouhscbbmc.github.io/REDCapR/reference/redcap_metadata_write.html) writes to the project's metadata. (#274, @felixetorres)

* [`redcap_survey_link_export_oneshot()`](https://ouhscbbmc.github.io/REDCapR/reference/redcap_survey_link_export_oneshot.html) retrieves the URL to a specific record's suvey (*e.g.*, "https://bbmc.ouhsc.edu/redcap/surveys/?s=8KuzSLMHf6") (#293)

### Stability Features

Expand Down
20 changes: 16 additions & 4 deletions R/redcap-read.R
Original file line number Diff line number Diff line change
Expand Up @@ -91,14 +91,26 @@
#'
#' @details
#' Specifically, it internally uses multiple calls to [redcap_read_oneshot()]
#' to select and return data. Initially, only primary key is queried through
#' the REDCap API. The long list is then subsetted into partitions, whose
#' sizes are determined by the `batch_size` parameter. REDCap is then
#' to select and return data. Initially, only the primary key is queried
#' through the REDCap API. The long list is then subsetted into batches,
#' whose sizes are determined by the `batch_size` parameter. REDCap is then
#' queried for all variables of the subset's subjects. This is repeated for
#' each subset, before returning a unified [base::data.frame()].
#'
#' The function allows a delay between calls, which allows the server to
#' attend to other users' requests.
#' attend to other users' requests (such as the users entering data in a
#' browser). In other words, a delay between batches does not bog down
#' the webserver when exporting/importing a large dataset.
#'
#' A second benefit is less RAM is required on the webserver. Because
#' each batch is smaller than the entire dataset, the webserver
#' tackles more managably sized objects in memory. Consider batching
#' if you encounter the error
#'
#' ```
#' ERROR: REDCap ran out of server memory. The request cannot be processed.
#' Please try importing/exporting a smaller amount of data.
#' ```
#'
#' For [redcap_read()] to function properly, the user must have Export
#' permissions for the 'Full Data Set'. Users with only 'De-Identified'
Expand Down
151 changes: 151 additions & 0 deletions R/redcap-survey-link-export-oneshot.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
#' @title Download a file from a REDCap project record
#'
#' @description This function uses REDCap's API to download a file.
#'
#' @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.
#' @param record The record ID where the file is to be imported. Required
#' @param instrument The name of the instrument associated with the
#' survey link. Required
#' @param event The name of the event where the file is saved in REDCap.
#' Optional
#' @param verbose A boolean value indicating if `message`s should be printed
#' to the R console during the operation. Optional.
#' @param config_options A list of options to pass to [httr::POST()] method
#' in the 'httr' package. See the details below. Optional.
#'
#' @return Currently, a list is returned with the following elements,
#' * `success`: A boolean value indicating if the operation was apparently
#' successful.
#' * `status_code`: The
#' [http status code](http://en.wikipedia.org/wiki/List_of_HTTP_status_codes)
#' of the operation.
#' * `outcome_message`: A human readable string indicating the operation's
#' outcome.
#' * `records_affected_count`: The number of records inserted or updated.
#' * `affected_ids`: The subject IDs of the inserted or updated records.
#' * `elapsed_seconds`: The duration of the function.
#' * `raw_text`: If an operation is NOT successful, the text returned by
#' REDCap. If an operation is successful, the `raw_text` is returned as an
#' empty string to save RAM.
#' * `file_name`: The name of the file persisted to disk. This is useful if
#' the name stored in REDCap is used (which is the default).
#'
#' @details
#' Currently, the function doesn't modify any variable types to conform to
#' REDCap's supported variables. See [validate_for_write()] for a helper
#' function that checks for some common important conflicts.
#'
#' **Permissions Required**
#' To use this method, you must have API Export privileges in the project.
#' (As stated in the 9.0.0 documentation.)
#'
#' @author Will Beasley
#'
#' @references The official documentation can be found on the 'API Help Page'
#' and 'API Examples' pages on the REDCap wiki (*i.e.*,
#' https://community.projectredcap.org/articles/456/api-documentation.html and
#' https://community.projectredcap.org/articles/462/api-examples.html).
#' If you do not have an account for the wiki, please ask your campus REDCap
#' administrator to send you the static material.
#'
#' @examples
#' \dontrun{
#' uri <- "https://bbmc.ouhsc.edu/redcap/api/"
#' token <- "8FA9A6BDAE2C0B5DD3CB472DD8E8918C" #pid=817
#' record <- 1
#' instrument <- "participant_morale_questionnaire"
#' # event <- "" # only for longitudinal projects
#'
#' result <- REDCapR::redcap_survey_link_export_oneshot(
#' record = record,
#' instrument = instrument,
#' redcap_uri = uri,
#' token = token
#' )
#' result$survey_link
#' }


#' @export
redcap_survey_link_export_oneshot <- function(
redcap_uri,
token,
record,
instrument,
event = "",
verbose = TRUE,
config_options = NULL
) {

checkmate::assert_character(redcap_uri, any.missing=FALSE, len=1, pattern="^.{1,}$")
checkmate::assert_character(token , any.missing=FALSE, len=1, pattern="^.{1,}$")
record <- as.character(record)
checkmate::assert_character(record , any.missing=FALSE, len=1, pattern="^.{1,}$")
checkmate::assert_character(instrument, any.missing=FALSE, len=1, pattern="^.{1,}$")
checkmate::assert_character(event , any.missing=FALSE, len=1, pattern="^.{0,}$")
checkmate::assert_logical( verbose , any.missing=FALSE)

token <- sanitize_token(token)
verbose <- verbose_prepare(verbose)

post_body <- list(
token = token,
content = "surveyLink",
record = record,
instrument = instrument,
event = event,
returnFormat = "csv"
)

if (0L < nchar(event)) post_body$event <- event

# This is the first of two important lines in the function.
# It retrieves the information from the server and stores it in RAM.
kernel <- kernel_api(redcap_uri, post_body, config_options)

if (kernel$success) {
if (verbose)
message("Preparing to export the survey link for the instrument `", instrument, "`.")

link <- kernel$raw_text

outcome_message <- sprintf(
"exported the survey link in %0.1f seconds, for instrument `%s`, record `%s`.",
kernel$elapsed_seconds,
instrument,
record
)

records_affected_count <- length(record)
record_id <- as.character(record)
kernel$raw_text <- ""
# If an operation is successful, the `raw_text` is no longer returned to
# save RAM. The content is not really necessary with httr's status
# message exposed.
} else { #If the operation was unsuccessful, then...
# kernel$status_code placeholder
outcome_message <- "survey link NOT returned."
records_affected_count <- 0L
record_id <- character(0) # Return an empty vector.
# kernel$raw_text
link <- character(0)
}

if (verbose)
message(outcome_message)

list(
survey_link = link,
success = kernel$success,
status_code = kernel$status_code,
outcome_message = outcome_message,
instrument = instrument,
records_affected_count = records_affected_count,
affected_ids = record_id,
elapsed_seconds = kernel$elapsed_seconds,
raw_text = kernel$raw_text
)
}
2 changes: 1 addition & 1 deletion R/redcap-variables.R
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ redcap_variables <- function(
if( verbose )
message(outcome_message)

list(
list(
data = ds,
success = kernel$success,
status_code = kernel$status_code,
Expand Down
Loading

0 comments on commit 9f9139e

Please sign in to comment.