diff --git a/DESCRIPTION b/DESCRIPTION index e5dc58eb..bc1f2240 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -24,7 +24,8 @@ Authors@R: c( person("Philip", "Chase", role="ctb"), person("Paddy", "Tobias", role = "ctb"), person("Michael", "Chirico", role = "ctb"), - person("William", "Sharp", role="ctb")) + person("William", "Sharp", role="ctb"), + person("Alexander", "StrĂ¼bing", role="ctb")) Maintainer: Shawn Garbett Description: Access data stored in 'REDCap' databases using the Application Programming Interface (API). 'REDCap' (Research Electronic Data CAPture; diff --git a/R/docsRecordsTypedMethods.R b/R/docsRecordsTypedMethods.R index 608db877..67a24803 100644 --- a/R/docsRecordsTypedMethods.R +++ b/R/docsRecordsTypedMethods.R @@ -42,7 +42,7 @@ #' Otherwise, records created or modified after this date will be returned. #' @param date_end `POSIXct(1)` or `NULL`. Ignored if `NULL` (default). #' Otherwise, records created or modified before this date will be returned. -#' @param csv_delimiter `character`. One of `c(",", "\t", ";", "|", "^")`. Designates the +#' @param csv_delimiter `character`. One of `c(",", ";", "\t", " ", "|", "^")`. Designates the #' delimiter for the CSV file received from the API. #' @param batch_size `integerish(1)` or `NULL`. When `NULL`, #' all records are pulled. Otherwise, the records all pulled in batches of this size. diff --git a/R/exportDags.R b/R/exportDags.R index 76d3bacd..c9b68546 100644 --- a/R/exportDags.R +++ b/R/exportDags.R @@ -11,28 +11,29 @@ exportDags <- function(rcon, ...){ #' @order 4 #' @export -exportDags.redcapApiConnection <- function(rcon, +exportDags.redcapApiConnection <- function(rcon, ...) { ################################################################### # Argument Validation #### - + coll <- checkmate::makeAssertCollection() - - checkmate::assert_class(x = rcon, - classes = "redcapApiConnection", + + checkmate::assert_class(x = rcon, + classes = "redcapApiConnection", add = coll) checkmate::reportAssertions(coll) - + ################################################################### # Make the API Body list #### - - body <- list(content = "dag", - format = "csv", - returnFormat = "csv") + + body <- list(content = "dag", + format = "csv", + returnFormat = "csv", + csvDelimiter = rcon$csv_delimiter()) ################################################################### # Call the API #### - as.data.frame(makeApiCall(rcon, body, ...)) + as.data.frame(makeApiCall(rcon, body, ...), sep = rcon$csv_delimiter()) } diff --git a/R/exportFieldNames.R b/R/exportFieldNames.R index 8b03c130..02403bbc 100644 --- a/R/exportFieldNames.R +++ b/R/exportFieldNames.R @@ -135,5 +135,6 @@ exportFieldNames.redcapApiConnection <- function(rcon, # Make the API Call ----------------------------------------------- read.csv(text = as.character(makeApiCall(rcon, body, ...)), na.strings = "", - stringsAsFactors = FALSE) + stringsAsFactors = FALSE, + sep = rcon$csv_delimiter()) } diff --git a/R/exportProjectInformation.R b/R/exportProjectInformation.R index e9aaee46..6ec4ddab 100644 --- a/R/exportProjectInformation.R +++ b/R/exportProjectInformation.R @@ -30,9 +30,10 @@ exportProjectInformation.redcapApiConnection <- function(rcon, body <- list(content = 'project', format = 'csv', - returnFormat = 'csv') + returnFormat = 'csv', + csvDelimiter = rcon$csv_delimiter()) ################################################################## # Call the API - as.data.frame(makeApiCall(rcon, body, ...)) + as.data.frame(makeApiCall(rcon, body, ...), sep = rcon$csv_delimiter()) } diff --git a/R/exportRecordsTyped.R b/R/exportRecordsTyped.R index 4f3f6232..7527f8f6 100644 --- a/R/exportRecordsTyped.R +++ b/R/exportRecordsTyped.R @@ -47,7 +47,7 @@ exportRecordsTyped.redcapApiConnection <- filter_empty_rows = TRUE, warn_zero_coded = TRUE, ..., - csv_delimiter = ",", + csv_delimiter = rcon$csv_delimiter(), batch_size = 100L) { logEvent("INFO", call='exportRecordsTyped', @@ -112,7 +112,7 @@ exportRecordsTyped.redcapApiConnection <- add = coll) csv_delimiter <- checkmate::matchArg(x = csv_delimiter, - choices = c(",", "\t", ";", "|", "^"), + choices = c(",", ";", "\t", " ", "|", "^"), .var.name = "csv_delimiter", add = coll) @@ -682,7 +682,8 @@ exportRecordsTyped.redcapOfflineConnection <- function(rcon, record_response <- makeApiCall(rcon, body = c(list(content = "record", format = "csv", - outputFormat = "csv"), + outputFormat = "csv", + csvDelimiter = rcon$csv_delimiter()), vectorToApiBodyList(target_field, "fields")), log=FALSE, diff --git a/R/exportReportsTyped.R b/R/exportReportsTyped.R index 4c7e514b..05ca544f 100644 --- a/R/exportReportsTyped.R +++ b/R/exportReportsTyped.R @@ -59,7 +59,7 @@ exportReportsTyped.redcapApiConnection <- function(rcon, add = coll) csv_delimiter <- checkmate::matchArg(x = csv_delimiter, - choices = c(",", "\t", ";", "|", "^"), + choices = c(",", ";", "\t", " ", "|", "^"), .var.name = "csv_delimiter", add = coll) diff --git a/R/importDags.R b/R/importDags.R index 2089fa5a..1ce8e56b 100644 --- a/R/importDags.R +++ b/R/importDags.R @@ -53,7 +53,7 @@ importDags.redcapApiConnection <- function(rcon, action = "import", format = "csv", returnFormat = "csv", - data = writeDataForImport(data)) + data = writeDataForImport(data, csv_delimiter = rcon$csv_delimiter())) ################################################################### # Call the API #### diff --git a/R/redcapConnection.R b/R/redcapConnection.R index 2b28603b..ed141a95 100644 --- a/R/redcapConnection.R +++ b/R/redcapConnection.R @@ -236,6 +236,9 @@ redcapConnection <- function(url = getOption('redcap_api_url'), length.out = rtry) rtry_q <- retry_quietly + # CSV delimiter state for this connection ------------------------- + csv_delim <- "," + getter <- function(export, ...){ switch(export, "metadata" = exportMetaData(rc), @@ -397,9 +400,20 @@ redcapConnection <- function(url = getOption('redcap_api_url'), len = 1, any.missing = FALSE) rtry_q <<- rq - } + }, + + set_csv_delimiter = function(d) { + checkmate::assert_choice( + x = d, + choices = c(",", ";", "\t", " ", "|", "^") + ) + csv_delim <<- d + }, + csv_delimiter = function() csv_delim ) class(rc) <- c("redcapApiConnection", "redcapConnection") + # Initialize csv_delimiter with default + rc$set_csv_delimiter(",") rc } diff --git a/R/writeDataForImport.R b/R/writeDataForImport.R index 2fc8b3fc..9c583061 100644 --- a/R/writeDataForImport.R +++ b/R/writeDataForImport.R @@ -5,9 +5,11 @@ #' of a CSV for import through the API. #' #' @param data `data.frame` to be imported to the API -#' +#' @param csv_delimiter `character(1)` Delimiter used to separate fields in the generated CSV +#' string. Defaults to `","`. +#' -writeDataForImport <- function(data){ +writeDataForImport <- function(data, csv_delimiter = ","){ coll <- checkmate::makeAssertCollection() checkmate::assert_data_frame(x = data, @@ -17,10 +19,13 @@ writeDataForImport <- function(data){ output <- utils::capture.output( - utils::write.csv(data, - file = "", - na = "", - row.names = FALSE) + utils::write.table(data, + file = "", + sep = csv_delimiter, + na = "", + row.names = FALSE, + col.names = TRUE, + qmethod = "double") ) paste0(output, collapse = "\n") diff --git a/man/recordsTypedMethods.Rd b/man/recordsTypedMethods.Rd index 332ceb79..c2137875 100644 --- a/man/recordsTypedMethods.Rd +++ b/man/recordsTypedMethods.Rd @@ -40,7 +40,7 @@ exportReportsTyped(rcon, report_id, ...) filter_empty_rows = TRUE, warn_zero_coded = TRUE, ..., - csv_delimiter = ",", + csv_delimiter = rcon$csv_delimiter(), batch_size = 100L ) @@ -150,7 +150,7 @@ HTML and UNICODE raw label and scanning for units=\{"UNITS"\} in description} \item{filter_empty_rows}{\code{logical(1)}. Filter out empty rows post retrieval. Defaults to \code{TRUE}.} -\item{csv_delimiter}{\code{character}. One of \code{c(",", "\\t", ";", "|", "^")}. Designates the +\item{csv_delimiter}{\code{character}. One of \code{c(",", ";", "\\t", " ", "|", "^")}. Designates the delimiter for the CSV file received from the API.} \item{batch_size}{\code{integerish(1)} or \code{NULL}. When \code{NULL}, diff --git a/man/redcapAPI.Rd b/man/redcapAPI.Rd index 17269fe1..69a384ff 100644 --- a/man/redcapAPI.Rd +++ b/man/redcapAPI.Rd @@ -56,6 +56,7 @@ Other contributors: \item Paddy Tobias [contributor] \item Michael Chirico [contributor] \item William Sharp [contributor] + \item Alexander StrĂ¼bing [contributor] } } diff --git a/man/writeDataForImport.Rd b/man/writeDataForImport.Rd index 57167297..8926a039 100644 --- a/man/writeDataForImport.Rd +++ b/man/writeDataForImport.Rd @@ -4,10 +4,13 @@ \alias{writeDataForImport} \title{Prepare a Data Frame for Import Through the API} \usage{ -writeDataForImport(data) +writeDataForImport(data, csv_delimiter = ",") } \arguments{ \item{data}{\code{data.frame} to be imported to the API} + +\item{csv_delimiter}{\code{character(1)} Delimiter used to separate fields in the generated CSV +string. Defaults to \code{","}.} } \description{ Converts a dataframe into a character value in the format