From 8fd2cd5afb0512a72f0802a296a84208fa348837 Mon Sep 17 00:00:00 2001 From: Will Beasley Date: Fri, 6 Sep 2024 15:58:16 -0500 Subject: [PATCH 1/3] accommodate readr's `na` parameter suggested by @rmtrane in #529 --- NEWS.md | 1 + R/redcap-read-oneshot.R | 5 ++ R/redcap-read.R | 5 ++ .../specific-redcapr/read-batch-simple/na.R | 52 +++++++++++++++++++ .../specific-redcapr/read-oneshot/na.R | 52 +++++++++++++++++++ tests/testthat/test-read-batch-simple.R | 37 +++++++++++++ tests/testthat/test-read-oneshot.R | 38 ++++++++++++++ 7 files changed, 190 insertions(+) create mode 100644 inst/test-data/specific-redcapr/read-batch-simple/na.R create mode 100644 inst/test-data/specific-redcapr/read-oneshot/na.R diff --git a/NEWS.md b/NEWS.md index f9ed1f7d..7b45511f 100644 --- a/NEWS.md +++ b/NEWS.md @@ -94,6 +94,7 @@ This will help extract forms from longitudinal & repeating projects. * The regex in `regex_named_captures()` is forgiving if there's an unnecessary leading space (@BlairCooper, #495, #501) * `redcap_log_read()` assumes all columns are character, except for `timestamp` (#525) * `redcap_file_download_oneshot()` no longer asks for the unnecessary parameter for `repeating_instrument` (that the REDCap server ignores). (@BlairCooper, #506, #530) +* `redcap_read()` and `redcap_read_oneshot()` accommodate `readr::read_csv()`'s parameter of `na`. (Suggested by @rmtrane in #529) Version 1.1.0 (released 2022-08-10) ========================================================== diff --git a/R/redcap-read-oneshot.R b/R/redcap-read-oneshot.R index 70b52da6..655010c7 100644 --- a/R/redcap-read-oneshot.R +++ b/R/redcap-read-oneshot.R @@ -60,6 +60,8 @@ #' REDCap project. Default is `FALSE`. #' @param col_types A [readr::cols()] object passed internally to #' [readr::read_csv()]. Optional. +#' @param na A [character] vector passed internally to [readr::read_csv()]. +#' Defaults to `c("", "NA")`. #' @param guess_type A boolean value indicating if all columns should be #' returned as character. If true, [readr::read_csv()] guesses the intended #' data type for each column. Ignored if `col_types` is not null. @@ -215,6 +217,7 @@ redcap_read_oneshot <- function( datetime_range_end = as.POSIXct(NA), blank_for_gray_form_status = FALSE, col_types = NULL, + na = c("", "NA"), guess_type = TRUE, guess_max = 1000, http_response_encoding = "UTF-8", @@ -244,6 +247,7 @@ redcap_read_oneshot <- function( checkmate::assert_posixct( datetime_range_end , any.missing=TRUE , len=1, null.ok=TRUE) checkmate::assert_logical( blank_for_gray_form_status , any.missing=FALSE, len=1) + checkmate::assert_character(na , any.missing=FALSE) checkmate::assert_logical( guess_type , any.missing=FALSE, len=1) checkmate::assert_numeric( guess_max , any.missing=FALSE, len=1, lower=1) @@ -329,6 +333,7 @@ redcap_read_oneshot <- function( readr::read_csv( file = I(kernel$raw_text), col_types = col_types, + na = na, guess_max = guess_max, locale = locale, show_col_types = FALSE diff --git a/R/redcap-read.R b/R/redcap-read.R index 3f0cef52..31df5131 100644 --- a/R/redcap-read.R +++ b/R/redcap-read.R @@ -73,6 +73,8 @@ #' REDCap project. Default is `FALSE`. #' @param col_types A [readr::cols()] object passed internally to #' [readr::read_csv()]. Optional. +#' @param na A [character] vector passed internally to [readr::read_csv()]. +#' Defaults to `c("", "NA")`. #' @param guess_type A boolean value indicating if all columns should be #' returned as character. If true, [readr::read_csv()] guesses the intended #' data type for each column. Ignored if `col_types` is not null. @@ -265,6 +267,7 @@ redcap_read <- function( blank_for_gray_form_status = FALSE, col_types = NULL, + na = c("", "NA"), guess_type = TRUE, guess_max = NULL, # Deprecated parameter http_response_encoding = "UTF-8", @@ -294,6 +297,7 @@ redcap_read <- function( checkmate::assert_posixct( datetime_range_end , any.missing=TRUE , len=1, null.ok=TRUE) checkmate::assert_logical( blank_for_gray_form_status , any.missing=FALSE, len=1) + checkmate::assert_character(na , any.missing=FALSE) checkmate::assert_logical( guess_type , any.missing=FALSE, len=1) if (!is.null(guess_max)) warning("The `guess_max` parameter in `REDCapR::redcap_read()` is deprecated.") @@ -468,6 +472,7 @@ redcap_read <- function( datetime_range_end = datetime_range_end, blank_for_gray_form_status = blank_for_gray_form_status, + na = na, col_types = col_types, guess_type = FALSE, # guess_max # Not used, because guess_type is FALSE diff --git a/inst/test-data/specific-redcapr/read-batch-simple/na.R b/inst/test-data/specific-redcapr/read-batch-simple/na.R new file mode 100644 index 00000000..6c876ead --- /dev/null +++ b/inst/test-data/specific-redcapr/read-batch-simple/na.R @@ -0,0 +1,52 @@ +structure(list(record_id = 1:5, name_first = c("Nutmeg", "Tumtum", +"Marcus", "Trudy", "John Lee"), name_last = c(NA, NA, "Wood", +"DAG", "Walker"), address = c("14 Rose Cottage St.\nKenning UK, 323232", +"14 Rose Cottage Blvd.\nKenning UK 34243", "243 Hill St.\nGuthrie OK 73402", +"342 Elm\nDuncanville TX, 75116", "Hotel Suite\nNew Orleans LA, 70115" +), telephone = c("(405) 321-1111", "(405) 321-2222", "(405) 321-3333", +"(405) 321-4444", "(405) 321-5555"), email = c("nutty@mouse.com", +"tummy@mouse.comm", "mw@mwood.net", "peroxide@blonde.com", "left@hippocket.com" +), dob = structure(c(12294, 12121, -13051, -6269, -5375), class = "Date"), + age = c(11, 11, 80, 61, 59), sex = c(0, 1, 1, 0, 1), demographics_complete = c(2, + 2, 2, 2, 2), height = c(7, 6, 180, 165, 193.04), weight = c(1, + 1, 80, 54, 104), bmi = c(204.1, 277.8, 24.7, 19.8, 27.9), + comments = c("Character in a book, with some guessing", "A mouse character from a good book", + "completely made up", "This record doesn't have a DAG assigned\n\nSo call up Trudy on the telephone\nSend her a letter in the mail", + "Had a hand for trouble and a eye for cash\n\nHe had a gold watch chain and a black mustache" + ), mugshot = c("mugshot-1.jpg", "mugshot-2.jpg", "mugshot-3.jpg", + "mugshot-4.jpg", "mugshot-5.jpg"), health_complete = c(1, + 0, 2, 2, 0), race___1 = c(FALSE, FALSE, FALSE, FALSE, TRUE + ), race___2 = c(FALSE, FALSE, FALSE, TRUE, FALSE), race___3 = c(FALSE, + TRUE, FALSE, FALSE, FALSE), race___4 = c(FALSE, FALSE, TRUE, + FALSE, FALSE), race___5 = c(TRUE, TRUE, TRUE, TRUE, FALSE + ), race___6 = c(FALSE, FALSE, FALSE, FALSE, TRUE), ethnicity = c(1, + 1, 0, 1, 2), interpreter_needed = c(0, 0, 1, NA, 0), race_and_ethnicity_complete = c(2, + 0, 2, 2, 2)), row.names = c(NA, -5L), spec = structure(list( + cols = list(record_id = structure(list(), class = c("collector_integer", + "collector")), name_first = structure(list(), class = c("collector_character", + "collector")), name_last = structure(list(), class = c("collector_logical", + "collector")), address = structure(list(), class = c("collector_character", + "collector")), telephone = structure(list(), class = c("collector_character", + "collector")), email = structure(list(), class = c("collector_character", + "collector")), dob = structure(list(format = ""), class = c("collector_date", + "collector")), age = structure(list(), class = c("collector_double", + "collector")), sex = structure(list(), class = c("collector_double", + "collector")), demographics_complete = structure(list(), class = c("collector_double", + "collector")), height = structure(list(), class = c("collector_double", + "collector")), weight = structure(list(), class = c("collector_double", + "collector")), bmi = structure(list(), class = c("collector_double", + "collector")), comments = structure(list(), class = c("collector_character", + "collector")), mugshot = structure(list(), class = c("collector_character", + "collector")), health_complete = structure(list(), class = c("collector_double", + "collector")), race___1 = structure(list(), class = c("collector_logical", + "collector")), race___2 = structure(list(), class = c("collector_logical", + "collector")), race___3 = structure(list(), class = c("collector_logical", + "collector")), race___4 = structure(list(), class = c("collector_logical", + "collector")), race___5 = structure(list(), class = c("collector_logical", + "collector")), race___6 = structure(list(), class = c("collector_logical", + "collector")), ethnicity = structure(list(), class = c("collector_double", + "collector")), interpreter_needed = structure(list(), class = c("collector_double", + "collector")), race_and_ethnicity_complete = structure(list(), class = c("collector_double", + "collector"))), default = structure(list(), class = c("collector_guess", + "collector")), delim = ","), class = "col_spec"), class = c("spec_tbl_df", +"tbl_df", "tbl", "data.frame")) diff --git a/inst/test-data/specific-redcapr/read-oneshot/na.R b/inst/test-data/specific-redcapr/read-oneshot/na.R new file mode 100644 index 00000000..fbb33235 --- /dev/null +++ b/inst/test-data/specific-redcapr/read-oneshot/na.R @@ -0,0 +1,52 @@ +structure(list(record_id = 1:5, name_first = c("Nutmeg", "Tumtum", +"Marcus", "Trudy", "John Lee"), name_last = c(NA, NA, "Wood", +"DAG", "Walker"), address = c("14 Rose Cottage St.\nKenning UK, 323232", +"14 Rose Cottage Blvd.\nKenning UK 34243", "243 Hill St.\nGuthrie OK 73402", +"342 Elm\nDuncanville TX, 75116", "Hotel Suite\nNew Orleans LA, 70115" +), telephone = c("(405) 321-1111", "(405) 321-2222", "(405) 321-3333", +"(405) 321-4444", "(405) 321-5555"), email = c("nutty@mouse.com", +"tummy@mouse.comm", "mw@mwood.net", "peroxide@blonde.com", "left@hippocket.com" +), dob = structure(c(12294, 12121, -13051, -6269, -5375), class = "Date"), + age = c(11, 11, 80, 61, 59), sex = c(0, 1, 1, 0, 1), demographics_complete = c(2, + 2, 2, 2, 2), height = c(7, 6, 180, 165, 193.04), weight = c(1, + 1, 80, 54, 104), bmi = c(204.1, 277.8, 24.7, 19.8, 27.9), + comments = c("Character in a book, with some guessing", "A mouse character from a good book", + "completely made up", "This record doesn't have a DAG assigned\n\nSo call up Trudy on the telephone\nSend her a letter in the mail", + "Had a hand for trouble and a eye for cash\n\nHe had a gold watch chain and a black mustache" + ), mugshot = c("mugshot-1.jpg", "mugshot-2.jpg", "mugshot-3.jpg", + "mugshot-4.jpg", "mugshot-5.jpg"), health_complete = c(1, + 0, 2, 2, 0), race___1 = c(FALSE, FALSE, FALSE, FALSE, TRUE + ), race___2 = c(FALSE, FALSE, FALSE, TRUE, FALSE), race___3 = c(FALSE, + TRUE, FALSE, FALSE, FALSE), race___4 = c(FALSE, FALSE, TRUE, + FALSE, FALSE), race___5 = c(TRUE, TRUE, TRUE, TRUE, FALSE + ), race___6 = c(FALSE, FALSE, FALSE, FALSE, TRUE), ethnicity = c(1, + 1, 0, 1, 2), interpreter_needed = c(0, 0, 1, NA, 0), race_and_ethnicity_complete = c(2, + 0, 2, 2, 2)), row.names = c(NA, -5L), spec = structure(list( + cols = list(record_id = structure(list(), class = c("collector_integer", + "collector")), name_first = structure(list(), class = c("collector_character", + "collector")), name_last = structure(list(), class = c("collector_character", + "collector")), address = structure(list(), class = c("collector_character", + "collector")), telephone = structure(list(), class = c("collector_character", + "collector")), email = structure(list(), class = c("collector_character", + "collector")), dob = structure(list(format = ""), class = c("collector_date", + "collector")), age = structure(list(), class = c("collector_double", + "collector")), sex = structure(list(), class = c("collector_double", + "collector")), demographics_complete = structure(list(), class = c("collector_double", + "collector")), height = structure(list(), class = c("collector_double", + "collector")), weight = structure(list(), class = c("collector_double", + "collector")), bmi = structure(list(), class = c("collector_double", + "collector")), comments = structure(list(), class = c("collector_character", + "collector")), mugshot = structure(list(), class = c("collector_character", + "collector")), health_complete = structure(list(), class = c("collector_double", + "collector")), race___1 = structure(list(), class = c("collector_logical", + "collector")), race___2 = structure(list(), class = c("collector_logical", + "collector")), race___3 = structure(list(), class = c("collector_logical", + "collector")), race___4 = structure(list(), class = c("collector_logical", + "collector")), race___5 = structure(list(), class = c("collector_logical", + "collector")), race___6 = structure(list(), class = c("collector_logical", + "collector")), ethnicity = structure(list(), class = c("collector_double", + "collector")), interpreter_needed = structure(list(), class = c("collector_double", + "collector")), race_and_ethnicity_complete = structure(list(), class = c("collector_double", + "collector"))), default = structure(list(), class = c("collector_guess", + "collector")), delim = ","), class = "col_spec"), class = c("spec_tbl_df", +"tbl_df", "tbl", "data.frame")) diff --git a/tests/testthat/test-read-batch-simple.R b/tests/testthat/test-read-batch-simple.R index c0ec4d55..3e906d8c 100644 --- a/tests/testthat/test-read-batch-simple.R +++ b/tests/testthat/test-read-batch-simple.R @@ -83,6 +83,43 @@ test_that("default", { expect_match(returned_object2$outcome_messages, regexp=expected_outcome_message, perl=TRUE) expect_s3_class(returned_object2$data, "tbl") }) +test_that("na", { + testthat::skip_on_cran() + path_expected <- "test-data/specific-redcapr/read-batch-simple/na.R" + col_types <- readr::cols( + record_id = readr::col_integer(), + race___1 = readr::col_logical(), + race___2 = readr::col_logical(), + race___3 = readr::col_logical(), + race___4 = readr::col_logical(), + race___5 = readr::col_logical(), + race___6 = readr::col_logical() + ) + + expected_outcome_message <- "\\d+ records and 25 columns were read from REDCap in \\d+(\\.\\d+\\W|\\W)seconds\\." + + returned_object <- + redcap_read( + redcap_uri = credential$redcap_uri, + token = credential$token, + na = c("", "NA", "Nutmouse"), + col_types = col_types, + batch_size = 2, + verbose = FALSE + ) + + if (update_expectation) save_expected(returned_object$data, path_expected) + expected_data_frame <- retrieve_expected(path_expected) + + expect_equal(returned_object$data, expected=expected_data_frame, label="The returned data.frame should be correct", ignore_attr = TRUE) # dput(returned_object$data) + expect_true( returned_object$success) + expect_match(returned_object$status_codes, regexp="200", perl=TRUE) + expect_true( returned_object$records_collapsed=="", "A subset of records was not requested.") + expect_true( returned_object$fields_collapsed=="", "A subset of fields was not requested.") + expect_true( returned_object$filter_logic=="", "A filter was not specified.") + expect_match(returned_object$outcome_messages, regexp=expected_outcome_message, perl=TRUE) + expect_s3_class(returned_object$data, "tbl") +}) test_that("col_types", { testthat::skip_on_cran() path_expected <- "test-data/specific-redcapr/read-batch-simple/col_types.R" diff --git a/tests/testthat/test-read-oneshot.R b/tests/testthat/test-read-oneshot.R index f3edceb0..c5852efb 100644 --- a/tests/testthat/test-read-oneshot.R +++ b/tests/testthat/test-read-oneshot.R @@ -41,6 +41,44 @@ test_that("default", { expect_s3_class(returned_object$data, "tbl") }) +test_that("na", { + testthat::skip_on_cran() + path_expected <- "test-data/specific-redcapr/read-oneshot/na.R" + expected_outcome_message <- "\\d+ records and \\d+ columns were read from REDCap in \\d+(\\.\\d+\\W|\\W)seconds\\." + + col_types <- readr::cols( + record_id = readr::col_integer(), + race___1 = readr::col_logical(), + race___2 = readr::col_logical(), + race___3 = readr::col_logical(), + race___4 = readr::col_logical(), + race___5 = readr::col_logical(), + race___6 = readr::col_logical() + ) + + returned_object <- + redcap_read_oneshot( + redcap_uri = credential$redcap_uri, + token = credential$token, + na = c("", "NA", "Nutmouse"), + col_types = col_types, + verbose = FALSE + ) + + if (update_expectation) save_expected(returned_object$data, path_expected) + expected_data_frame <- retrieve_expected(path_expected) + + expect_equal(returned_object$data, expected=expected_data_frame, label="The returned data.frame should be correct", ignore_attr = TRUE) # dput(returned_object$data) + expect_equal(returned_object$status_code, expected=200L) + expect_equal(returned_object$raw_text, expected="", ignore_attr = TRUE) # dput(returned_object$raw_text) + expect_true(returned_object$records_collapsed=="", "A subset of records was not requested.") + expect_true(returned_object$fields_collapsed=="", "A subset of fields was not requested.") + expect_true(returned_object$filter_logic=="", "A filter was not specified.") + expect_match(returned_object$outcome_message, regexp=expected_outcome_message, perl=TRUE) + expect_true(returned_object$success) + + expect_s3_class(returned_object$data, "tbl") +}) test_that("col_types", { testthat::skip_on_cran() path_expected <- "test-data/specific-redcapr/read-oneshot/col_types.R" From 4f33e4332e941041b96ce0b436b3a2e4193e0bf2 Mon Sep 17 00:00:00 2001 From: Will Beasley Date: Fri, 6 Sep 2024 16:02:26 -0500 Subject: [PATCH 2/3] straggler from #530 --- .../project-longitudinal/dictionary.csv | 99 +------------------ .../project-longitudinal/project.xml | 31 +++--- 2 files changed, 20 insertions(+), 110 deletions(-) diff --git a/inst/test-data/project-longitudinal/dictionary.csv b/inst/test-data/project-longitudinal/dictionary.csv index 78972dee..c6c8f6a4 100644 --- a/inst/test-data/project-longitudinal/dictionary.csv +++ b/inst/test-data/project-longitudinal/dictionary.csv @@ -1,96 +1,5 @@ "Variable / Field Name","Form Name","Section Header","Field Type","Field Label","Choices, Calculations, OR Slider Labels","Field Note","Text Validation Type OR Show Slider Number","Text Validation Min","Text Validation Max",Identifier?,"Branching Logic (Show field only if...)","Required Field?","Custom Alignment","Question Number (surveys only)","Matrix Group Name","Matrix Ranking?","Field Annotation" -study_id,demographics,,text,"Study ID",,,,,,,,,,,,, -date_enrolled,demographics,"Consent Information",text,"Date subject signed consent",,YYYY-MM-DD,date_ymd,,,,,,,,,, -patient_document,demographics,,file,"Upload the patient's consent form",,,,,,,,,,,,, -first_name,demographics,"Contact Information",text,"First Name",,,,,,y,,,,,,, -last_name,demographics,,text,"Last Name",,,,,,y,,,,,,, -telephone_1,demographics,,text,"Phone number",,"Include Area Code",phone,,,y,,,,,,, -email,demographics,,text,E-mail,,,email,,,y,,,,,,, -dob,demographics,,text,"Date of birth",,,date_ymd,,,y,,,,,,, -age,demographics,,calc,"Age (years)","rounddown(datediff([dob],'today','y'))",,,,,,,,,,,, -ethnicity,demographics,,radio,Ethnicity,"0, Hispanic or Latino | 1, NOT Hispanic or Latino | 2, Unknown / Not Reported",,,,,,,,LH,,,, -race,demographics,,dropdown,Race,"0, American Indian/Alaska Native | 1, Asian | 2, Native Hawaiian or Other Pacific Islander | 3, Black or African American | 4, White | 5, More Than One Race | 6, Unknown / Not Reported",,,,,,,,,,,, -sex,demographics,,radio,Gender,"0, Female | 1, Male",,,,,,,,,,,, -given_birth,demographics,,yesno,"Has the patient given birth before?",,,,,,,"[sex] = ""0""",,,,,, -num_children,demographics,,text,"How many times has the patient given birth?",,,integer,0,,,"[sex] = ""0"" and [given_birth] = ""1""",,,,,, -gym,demographics,"Please provide the patient's weekly schedule for the activities below.",checkbox,"Gym (Weight Training)","0, Monday | 1, Tuesday | 2, Wednesday | 3, Thursday | 4, Friday",,,,,,,,,,weekly_schedule,, -aerobics,demographics,,checkbox,Aerobics,"0, Monday | 1, Tuesday | 2, Wednesday | 3, Thursday | 4, Friday",,,,,,,,,,weekly_schedule,, -eat,demographics,,checkbox,"Eat Out (Dinner/Lunch)","0, Monday | 1, Tuesday | 2, Wednesday | 3, Thursday | 4, Friday",,,,,,,,,,weekly_schedule,, -drink,demographics,,checkbox,"Drink (Alcoholic Beverages)","0, Monday | 1, Tuesday | 2, Wednesday | 3, Thursday | 4, Friday",,,,,,,,,,weekly_schedule,, -specify_mood,demographics,"Other information",slider,"Specify the patient's mood","Very sad | Indifferent | Very happy",,,,,,,,RH,,,, -meds,demographics,,checkbox,"Is patient taking any of the following medications? (check all that apply)","1, Lexapro | 2, Celexa | 3, Prozac | 4, Paxil | 5, Zoloft",,,,,,,,,,,, -height,demographics,,text,"Height (cm)",,,number,130,215,,,,,,,, -weight,demographics,,text,"Weight (kilograms)",,,integer,35,200,,,,,,,, -bmi,demographics,,calc,BMI,"round(([weight]*10000)/(([height])^(2)),1)",,,,,,,,,,,, -comments,demographics,"General Comments",notes,Comments,,,,,,,,,,,,, -ec_phone,contact_info,,text,"Emergency Contact Phone Number",,"Include Area Code",phone,,,,,,,,,, -ec_confirmed,contact_info,,radio,Confirmed?,"0, No | 1, Yes",,,,,,,,,,,, -next_of_kin_contact_name,contact_info,,text,"Next of Kin Contact Name",,,,,,,,,,,,, -next_of_kin_contact_address,contact_info,,notes,"Next of Kin Contact Address",,,,,,,,,,,,, -next_of_kin_contact_phone,contact_info,,text,"Next of Kin Contact Phone Number",,"Include Area Code",phone,,,,,,,,,, -next_of_kin_confirmed,contact_info,,radio,Confirmed?,"0, No | 1, Yes",,,,,,,,,,,, -height2,baseline_data,,text,"Height (cm)",,,number,,,,,,,,,, -weight2,baseline_data,,text,"Weight (kilograms)",,,integer,,,,,,,,,, -bmi2,baseline_data,,calc,BMI,"round(([weight2]*10000)/(([height2])^(2)),1)",,,,,,,,,,,, -prealb_b,baseline_data,,text,"Serum Prealbumin (mg/dL)",,,number,,,,,,,,,, -creat_b,baseline_data,,text,"Creatinine (mg/dL)",,,number,,,,,,,,,, -npcr_b,baseline_data,,text,"Normalized Protein Catabolic Rate (g/kg/d)",,,number,,,,,,,,,, -chol_b,baseline_data,,text,"Cholesterol (mg/dL)",,,number,,,,,,,,,, -transferrin_b,baseline_data,,text,"Transferrin (mg/dL)",,,number,,,,,,,,,, -vld1,visit_lab_data,,text,"Serum Prealbumin (mg/dL)",,,number,,,,,,,,,, -vld2,visit_lab_data,,text,"Creatinine (mg/dL)",,,number,,,,,,,,,, -vld3,visit_lab_data,,text,"Normalized Protein Catabolic Rate (g/kg/d)",,,number,,,,,,,,,, -vld4,visit_lab_data,,text,"Cholesterol (mg/dL)",,,number,,,,,,,,,, -vld5,visit_lab_data,,text,"Transferrin (mg/dL)",,,number,,,,,,,,,, -pmq1,patient_morale_questionnaire,,dropdown,"On average, how many pills did you take each day last week?","0, less than 5 | 1, 5-10 | 2, 6-15 | 3, over 15",,,,,,,,,,,, -pmq2,patient_morale_questionnaire,,dropdown,"Using the handout, which level of dependence do you feel you are currently at?","0, 0 | 1, 1 | 2, 2 | 3, 3 | 4, 4 | 5, 5",,,,,,,,,,,, -pmq3,patient_morale_questionnaire,,radio,"Would you be willing to discuss your experiences with a psychiatrist?","0, No | 1, Yes",,,,,,,,,,,, -pmq4,patient_morale_questionnaire,,dropdown,"How open are you to further testing?","0, not open | 1, undecided | 2, very open",,,,,,,,,,,, -vbw1,visit_blood_workup,,text,"Serum Prealbumin (mg/dL)",,,number,,,,,,,,,, -vbw2,visit_blood_workup,,text,"Creatinine (mg/dL)",,,number,,,,,,,,,, -vbw3,visit_blood_workup,,text,"Normalized Protein Catabolic Rate (g/kg/d)",,,number,,,,,,,,,, -vbw4,visit_blood_workup,,text,"Cholesterol (mg/dL)",,,number,,,,,,,,,, -vbw5,visit_blood_workup,,text,"Transferrin (mg/dL)",,,number,,,,,,,,,, -vbw6,visit_blood_workup,,radio,"Blood draw shift?","0, AM | 1, PM",,,,,,,,,,,, -vbw7,visit_blood_workup,,radio,"Blood draw by","0, RN | 1, LPN | 2, nurse assistant | 3, doctor",,,,,,,,,,,, -vbw8,visit_blood_workup,,dropdown,"Level of patient anxiety","0, not anxious | 1, undecided | 2, very anxious",,,,,,,,,,,, -vbw9,visit_blood_workup,,dropdown,"Patient scheduled for future draws?","0, No | 1, Yes",,,,,,,,,,,, -vob1,visit_observed_behavior,"Was the patient...",radio,nervous?,"0, No | 1, Yes",,,,,,,,,,,, -vob2,visit_observed_behavior,,radio,worried?,"0, No | 1, Yes",,,,,,,,,,,, -vob3,visit_observed_behavior,,radio,scared?,"0, No | 1, Yes",,,,,,,,,,,, -vob4,visit_observed_behavior,,radio,fidgety?,"0, No | 1, Yes",,,,,,,,,,,, -vob5,visit_observed_behavior,,radio,crying?,"0, No | 1, Yes",,,,,,,,,,,, -vob6,visit_observed_behavior,,radio,screaming?,"0, No | 1, Yes",,,,,,,,,,,, -vob7,visit_observed_behavior,,notes,other,,,,,,,,,,,,, -vob8,visit_observed_behavior,"Were you...",radio,nervous?,"0, No | 1, Yes",,,,,,,,,,,, -vob9,visit_observed_behavior,,radio,worried?,"0, No | 1, Yes",,,,,,,,,,,, -vob10,visit_observed_behavior,,radio,scared?,"0, No | 1, Yes",,,,,,,,,,,, -vob11,visit_observed_behavior,,radio,fidgety?,"0, No | 1, Yes",,,,,,,,,,,, -vob12,visit_observed_behavior,,radio,crying?,"0, No | 1, Yes",,,,,,,,,,,, -vob13,visit_observed_behavior,,radio,screaming?,"0, No | 1, Yes",,,,,,,,,,,, -vob14,visit_observed_behavior,,notes,other,,,,,,,,,,,,, -study_comments,completion_data,,notes,Comments,,,,,,,,,,,,, -complete_study,completion_data,,dropdown,"Has patient completed study?","0, No | 1, Yes",,,,,,,,,,,, -withdraw_date,completion_data,,text,"Put a date if patient withdrew study",,,date_ymd,,,,,,,,,, -date_visit_4,completion_data,,text,"Date of last visit",,,date_ymd,,,,,,,,,, -alb_4,completion_data,,text,"Serum Albumin (g/dL)",,,number,,,,,,,,,, -prealb_4,completion_data,,text,"Serum Prealbumin (mg/dL)",,,number,,,,,,,,,, -creat_4,completion_data,,text,"Creatinine (mg/dL)",,,date_ymd,,,,,,,,,, -discharge_date_4,completion_data,,text,"Date of hospital discharge",,,date_ymd,,,,,,,,,, -discharge_summary_4,completion_data,,dropdown,"Discharge summary in patients binder?","0, No | 1, Yes",,,,,,,,,,,, -npcr_4,completion_data,,text,"Normalized Protein Catabolic Rate (g/kg/d)",,,integer,,,,,,,,,, -chol_4,completion_data,,text,"Cholesterol (mg/dL)",,,integer,,,,,,,,,, -withdraw_reason,completion_data,,dropdown,"Reason patient withdrew from study","0, Non-compliance | 1, Did not wish to continue in study | 2, Could not tolerate the supplement | 3, Hospitalization | 4, Other",,,,,,,,,,,, -cpq1,completion_project_questionnaire,,text,"Date of study completion",,,date_ymd,,,,,,,,,, -cpq2,completion_project_questionnaire,,text,"Transferrin (mg/dL)",,,integer,,,,,,,,,, -cpq3,completion_project_questionnaire,,text,Kt/V,,,integer,,,,,,,,,, -cpq4,completion_project_questionnaire,,text,"Dry weight (kilograms)",,,integer,,,,,,,,,, -cpq5,completion_project_questionnaire,,text,"Number of treatments missed",,,integer,,,,,,,,,, -cpq6,completion_project_questionnaire,,dropdown,"How compliant was the patient in drinking the supplement?","0, 100 percent | 1, 99-75 percent | 2, 74-50 percent | 3, 49-25 percent | 4, 0-24 percent",,,,,,,,,,,, -cpq7,completion_project_questionnaire,,dropdown,"Was patient hospitalized since last visit?","0, No | 1, Yes",,,,,,,,,,,, -cpq8,completion_project_questionnaire,,dropdown,"What was the cause of hospitalization?","1, Vascular access related events | 2, CVD events | 3, Other",,,,,,,,,,,, -cpq9,completion_project_questionnaire,,text,"Date of hospital admission",,,date_ymd,,,,,,,,,, -cpq10,completion_project_questionnaire,,dropdown,"On average, how many pills did you take each day last week?","0, less than 5 | 1, 5-10 | 2, 6-15 | 3, over 15",,,,,,,,,,,, -cpq11,completion_project_questionnaire,,dropdown,"Using the handout, which level of dependence do you feel you are currently at?","0, 0 | 1, 1 | 2, 2 | 3, 3 | 4, 4 | 5, 5",,,,,,,,,,,, -cpq12,completion_project_questionnaire,,radio,"Would you be willing to discuss your experiences with a psychiatrist?","0, No | 1, Yes",,,,,,,,,,,, -cpq13,completion_project_questionnaire,,dropdown,"How open are you to further testing?","0, not open | 1, undecided | 2, very open",,,,,,,,,,,, +record_id,collection,,text,"Record ID",,,,,,,,,,,,, +interview_date,collection,,text,interview_date,,,date_ymd,,,,,,,,,, +weight,collection,,text,weight,,,,,,,,,,,,, +image_profile,collection,,file,"Picture of fake patient",,,,,,,,,,,,, diff --git a/inst/test-data/project-longitudinal/project.xml b/inst/test-data/project-longitudinal/project.xml index fd1a3274..07e8c1f3 100644 --- a/inst/test-data/project-longitudinal/project.xml +++ b/inst/test-data/project-longitudinal/project.xml @@ -1,5 +1,5 @@ - + REDCapR Longitudinal Single Arm @@ -8,33 +8,30 @@ 1 + 1 + 1 0 0 + 1 + 0 + 0 + 1 + + 0 4 Longitudinal project with only one arm - - 0 - 0 - 0 - 0 - 0 - 1 - 0 0 ALL - + - - - - + @@ -57,6 +54,7 @@ + @@ -70,6 +68,9 @@ weight + + Picture of fake patient + Complete? @@ -81,7 +82,7 @@ - + From 961efb4ad4b07e764e23d91a216e0cad7ee49785 Mon Sep 17 00:00:00 2001 From: Will Beasley Date: Fri, 6 Sep 2024 16:29:27 -0500 Subject: [PATCH 3/3] documentation updates ref #529 --- man/redcap_read.Rd | 4 ++++ man/redcap_read_oneshot.Rd | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/man/redcap_read.Rd b/man/redcap_read.Rd index b666a6f8..3738f464 100644 --- a/man/redcap_read.Rd +++ b/man/redcap_read.Rd @@ -25,6 +25,7 @@ redcap_read( datetime_range_end = as.POSIXct(NA), blank_for_gray_form_status = FALSE, col_types = NULL, + na = c("", "NA"), guess_type = TRUE, guess_max = NULL, http_response_encoding = "UTF-8", @@ -117,6 +118,9 @@ REDCap project. Default is \code{FALSE}.} \item{col_types}{A \code{\link[readr:cols]{readr::cols()}} object passed internally to \code{\link[readr:read_delim]{readr::read_csv()}}. Optional.} +\item{na}{A \link{character} vector passed internally to \code{\link[readr:read_delim]{readr::read_csv()}}. +Defaults to \code{c("", "NA")}.} + \item{guess_type}{A boolean value indicating if all columns should be returned as character. If true, \code{\link[readr:read_delim]{readr::read_csv()}} guesses the intended data type for each column. Ignored if \code{col_types} is not null.} diff --git a/man/redcap_read_oneshot.Rd b/man/redcap_read_oneshot.Rd index 46baca4c..49153b7b 100644 --- a/man/redcap_read_oneshot.Rd +++ b/man/redcap_read_oneshot.Rd @@ -21,6 +21,7 @@ redcap_read_oneshot( datetime_range_end = as.POSIXct(NA), blank_for_gray_form_status = FALSE, col_types = NULL, + na = c("", "NA"), guess_type = TRUE, guess_max = 1000, http_response_encoding = "UTF-8", @@ -102,6 +103,9 @@ REDCap project. Default is \code{FALSE}.} \item{col_types}{A \code{\link[readr:cols]{readr::cols()}} object passed internally to \code{\link[readr:read_delim]{readr::read_csv()}}. Optional.} +\item{na}{A \link{character} vector passed internally to \code{\link[readr:read_delim]{readr::read_csv()}}. +Defaults to \code{c("", "NA")}.} + \item{guess_type}{A boolean value indicating if all columns should be returned as character. If true, \code{\link[readr:read_delim]{readr::read_csv()}} guesses the intended data type for each column. Ignored if \code{col_types} is not null.}