diff --git a/NAMESPACE b/NAMESPACE index a3563d2..c1164ca 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -23,12 +23,14 @@ export(get_bulk_order_detail) export(get_bulk_order_items) export(get_bulk_orders) export(get_bulk_query) +export(get_bulk_site_details) export(get_event_id) export(get_find_study_id) export(get_order_detail) export(get_order_items) export(get_orders) export(get_os_query) +export(get_os_site) export(get_patient_id) export(get_site_id) export(get_specimen_type_id) @@ -41,6 +43,7 @@ export(parse_order_detail_data) export(parse_os_oder_list) export(parse_os_order_data) export(parse_os_response) +export(parse_site_details) export(process_save_selected_aliquots) export(read_multiple_files) export(read_multiple_sheets) diff --git a/R/get_bulk_site_details.R b/R/get_bulk_site_details.R new file mode 100644 index 0000000..7c99037 --- /dev/null +++ b/R/get_bulk_site_details.R @@ -0,0 +1,53 @@ +# WARNING - Generated by {fusen} from dev/OpenSpecimenAPI.Rmd: do not edit by hand + +#' Get Bulk Site Details +#' +#' Use this function to retrieve details of multiple sites in bulk from the OpenSpecimen application. +#' +#' @param auth_response The authentication response object. +#' @param site_ids A vector of integers representing the IDs of the sites to retrieve details for. +#' @param ... Additional parameters to be passed to the underlying `get_os_site` function. +#' +#' @return A data table containing the details of the requested sites. +#' +#' @export +#' @examples +#' #get_bulk_site_details() +get_bulk_site_details <- function(auth_response, site_ids, ...) { + + # Check if site_ids is a vector of integers + if (isTRUE(any(round(site_ids) != site_ids))) { + stop("site_ids must be an integer") + } + + # Use tryCatch to handle errors + + list_dfs <- vector("list", length(site_ids)) + + for (i in seq_along(site_ids)) { + + list_dfs[[i]] <- tryCatch( + get_os_site(auth_response, site_id = site_ids[i], ...), + error = function(e) { + cli::cli_alert_warning(paste0("Error in site id: ", site_ids[i], " ", e$message)) + return(NULL) + } + ) + + if (i %% 10 == 0) { + cli::cli_alert_success( + paste0("Retrieved ", i, " sites", + " out of ", length(site_ids)) + ) + } + } + + ## Combine the list of data.tables into a single data.table + dt_final = data.table::rbindlist(list_dfs, fill = TRUE) + + cli::cli_alert_success(paste0("Done: Site details retrieved")) + + return(dt_final) + +} + diff --git a/R/get_os_site.R b/R/get_os_site.R new file mode 100644 index 0000000..ff9879b --- /dev/null +++ b/R/get_os_site.R @@ -0,0 +1,47 @@ +# WARNING - Generated by {fusen} from dev/OpenSpecimenAPI.Rmd: do not edit by hand + +#' Get OpenSpecimen Site +#' +#' Use this function to retrieve details of a site from the OpenSpecimen application. +#' +#' @param auth_response Authentication response object obtained from the OpenSpecimen API. +#' @param site_id The unique identifier of the site to fetch. +#' +#' @return A data frame containing the details of the specified site. +#' +#' @export +#' @examples +#' #get_os_site() +get_os_site <- function(auth_response, site_id) { + + # Get the site details + # Specify the content type as JSON in the header + # Extract the authentication token from the response + auth_token <- auth_response$auth_response$token + url <- auth_response$url + + headers <- add_headers( + "Content-Type" = "application/json", + "X-OS-API-TOKEN" = auth_token + ) + + # Make the GET request for the query + response <- GET( + url = paste0(url, "/sites/", site_id), + config = headers, + encode = "json" + ) + + # Parse the response and return the results + results <- parse_os_response(response, + parse_data_function = "parse_site_details") + + # If inherits data.frame, return results, else return NULL + if (inherits(results, "data.frame")) { + return(results) + } else { + return(NULL) + } + +} + diff --git a/R/parse_os_response.R b/R/parse_os_response.R index d188afa..15c5c7f 100644 --- a/R/parse_os_response.R +++ b/R/parse_os_response.R @@ -30,7 +30,9 @@ parse_os_response <- function(response, parse_data_function) { # if inherits data.frame apply timestamp_to_date if(inherits(df, "data.frame")){ - df <- timestamp_to_date(df) + + + timestamp_to_date(df) } return(df) diff --git a/R/parse_site_details.R b/R/parse_site_details.R new file mode 100644 index 0000000..69f1429 --- /dev/null +++ b/R/parse_site_details.R @@ -0,0 +1,51 @@ +# WARNING - Generated by {fusen} from dev/OpenSpecimenAPI.Rmd: do not edit by hand + +#' Parse OpenSpecimen Site Details +#' +#' Use this function to parse the response and extract details of a site from the OpenSpecimen application. +#' +#' @param response The API response object. +#' +#' @return A data table containing the parsed details of the site. +#' +#' @export +#' @examples +#' #parse_site_details() +parse_site_details <- function(response) { + + # Extract the content from the response + mycontent2 <- content(response, "parsed") + + # Extract extension details + extension_details <- mycontent2$extensionDetail + + # Extract attribute details + attr_dp <- extension_details$attrs + + # Create clean column names + col_nms <- sapply(attr_dp, function(x) x$caption) %>% + janitor::make_clean_names() + + # Extract attribute values + values <- lapply(attr_dp, function(x) x$value) + + # Set names for values + names(values) <- col_nms + + # Convert values to data.table + dt1 = as.data.table(values) + + # Remove extension details from parsed content + mycontent2$extensionDetail <- NULL + mycontent2$coordinators <- NULL + # Convert remaining parsed content to data.table + mycontentdf <- mycontent2 %>% as.data.table() + + # Combine data.tables + mycontentdf <- cbind(mycontentdf, dt1) + + # Return the final data.table + mycontentdf + +} + diff --git a/R/timestamp_to_date.R b/R/timestamp_to_date.R index da76129..dfa4980 100644 --- a/R/timestamp_to_date.R +++ b/R/timestamp_to_date.R @@ -72,9 +72,15 @@ timestamp_to_date.data.frame <- function(timestamp, date_cols = NULL){ data.table::setDT(timestamp) + leng <- length(date_cols) + + if(leng != 0){ + + timestamp[, (date_cols) := lapply(.SD, timestamp_to_date.numeric), .SDcols = date_cols] + } + - timestamp[, (date_cols) := lapply(.SD, timestamp_to_date.numeric), .SDcols = date_cols] diff --git a/README.Rmd b/README.Rmd index a6711da..c8f3bd2 100644 --- a/README.Rmd +++ b/README.Rmd @@ -277,3 +277,12 @@ sites <- get_all_sites(auth_response) kable(sites[1:5]) ``` + +## Get all Sites details + +```{r, message=FALSE} + +sites_details <- get_bulk_site_details(auth_response, + site_ids = sites$id) +kable(sites_details[1:5]) +``` diff --git a/README.md b/README.md index 05b3437..84bebc6 100644 --- a/README.md +++ b/README.md @@ -325,9 +325,6 @@ query114 <- get_os_query(auth_response, query_id = 114, wide_row_mode = "OFF", start_at = 0, max_results = 5) -#> Warning in `[.data.table`(timestamp, , `:=`((date_cols), lapply(.SD, -#> timestamp_to_date.numeric)), : length(LHS)==0; no columns to delete or assign -#> RHS to. kable(query114) ``` @@ -345,21 +342,9 @@ kable(query114) ``` r cv_samples <- get_bulk_query(auth_response, query_id = 105) -#> Warning in `[.data.table`(timestamp, , `:=`((date_cols), lapply(.SD, -#> timestamp_to_date.numeric)), : length(LHS)==0; no columns to delete or assign -#> RHS to. #> ✔ 5,000 rows retrieved -#> Warning in `[.data.table`(timestamp, , `:=`((date_cols), lapply(.SD, -#> timestamp_to_date.numeric)), : length(LHS)==0; no columns to delete or assign -#> RHS to. #> ✔ 10,000 rows retrieved -#> Warning in `[.data.table`(timestamp, , `:=`((date_cols), lapply(.SD, -#> timestamp_to_date.numeric)), : length(LHS)==0; no columns to delete or assign -#> RHS to. #> ✔ 15,000 rows retrieved -#> Warning in `[.data.table`(timestamp, , `:=`((date_cols), lapply(.SD, -#> timestamp_to_date.numeric)), : length(LHS)==0; no columns to delete or assign -#> RHS to. #> ✔ 18,897 rows retrieved @@ -382,9 +367,6 @@ orders <- get_bulk_orders(auth_response) #> ✔ 36 rows retrieved #> Warning in `[.data.table`(df, , `:=`((personal_info), NULL)): length(LHS)==0; #> no columns to delete or assign RHS to. -#> Warning in `[.data.table`(timestamp, , `:=`((date_cols), lapply(.SD, -#> timestamp_to_date.numeric)), : length(LHS)==0; no columns to delete or assign -#> RHS to. kable(orders[1:5]) ``` @@ -456,9 +438,6 @@ kable(distributed_samples[1:5]) ``` r sites <- get_all_sites(auth_response) -#> Warning in `[.data.table`(timestamp, , `:=`((date_cols), lapply(.SD, -#> timestamp_to_date.numeric)), : length(LHS)==0; no columns to delete or assign -#> RHS to. kable(sites[1:5]) ``` @@ -469,3 +448,22 @@ kable(sites[1:5]) | 130 | Access Bio, Inc | Access Bio, Inc | NA | Not Specified | Active | 0 | | 131 | Alere Technologies GmbH | Alere Technologies GmbH | NA | Not Specified | Active | 0 | | 124 | ARC | American Red Cross | NA | Collection Site | Active | 0 | + +## Get all Sites details + +``` r + +sites_details <- get_bulk_site_details(auth_response, + site_ids = sites$id) +kable(sites_details[1:5]) +``` + +| id | name | instituteName | code | type | activityStatus | cpCount | address | country | +|-------------------------:|:------------------------|:----------------------------------|:-----|:----------------|:---------------|--------:|:---------------------------------------------------------------------------------------------------|:--------| +| 80 | AAMI | Australian Army Malaria Institute | 09 | Not Specified | Active | 0 | Australian Army Malaria InstituteWeary Dunlop DriveGallipoli Barracks, Enoggera Qld Australia 4051 | NA | +| 132 | Access Bio Site 2 | Access Bio, Inc | NA | Not Specified | Active | 0 | other dept, 65 Clude Rd Suite A, | | +| Somerset, NJ, 08873, USA | NA | | | | | | | | +| 130 | Access Bio, Inc | Access Bio, Inc | NA | Not Specified | Active | 0 | 65 Clude Rd Suite A, | | +| Somerset, NJ, 08873, USA | NA | | | | | | | | +| 131 | Alere Technologies GmbH | Alere Technologies GmbH | NA | Not Specified | Active | 0 | Loebstedter Str. 103-105, Jena, 07749, Germany | NA | +| 124 | ARC | American Red Cross | NA | Collection Site | Active | 0 | NA | NA | diff --git a/dev/OpenSpecimenAPI.Rmd b/dev/OpenSpecimenAPI.Rmd index eac41f0..40fce60 100644 --- a/dev/OpenSpecimenAPI.Rmd +++ b/dev/OpenSpecimenAPI.Rmd @@ -159,9 +159,15 @@ timestamp_to_date.data.frame <- function(timestamp, date_cols = NULL){ data.table::setDT(timestamp) + leng <- length(date_cols) + + if(leng != 0){ + + timestamp[, (date_cols) := lapply(.SD, timestamp_to_date.numeric), .SDcols = date_cols] + } + - timestamp[, (date_cols) := lapply(.SD, timestamp_to_date.numeric), .SDcols = date_cols] @@ -171,6 +177,7 @@ timestamp_to_date.data.frame <- function(timestamp, date_cols = NULL){ ``` + ```{r example-timestamp_to_date} timestamp <- 1637892323000 @@ -186,6 +193,8 @@ timestamp_to_date(df) df ``` + + ```{r tests-timestamp_to_date} test_that("timestamp_to_date works", { expect_true(inherits(timestamp_to_date, "function")) @@ -223,7 +232,9 @@ parse_os_response <- function(response, parse_data_function) { # if inherits data.frame apply timestamp_to_date if(inherits(df, "data.frame")){ - df <- timestamp_to_date(df) + + + timestamp_to_date(df) } return(df) @@ -1173,10 +1184,13 @@ get_bulk_order_items <- function(auth_response, orders_ids, ...) { ``` + ```{r example-get_bulk_order_items} #get_bulk_order_items() ``` + + ```{r tests-get_bulk_order_items} test_that("get_bulk_order_items works", { expect_true(inherits(get_bulk_order_items, "function")) @@ -1185,6 +1199,7 @@ test_that("get_bulk_order_items works", { + # get_all_sites ```{r function-get_all_sites} @@ -1245,6 +1260,197 @@ test_that("get_all_sites works", { +# parse_site_details + +```{r function-parse_site_details} +#' Parse OpenSpecimen Site Details +#' +#' Use this function to parse the response and extract details of a site from the OpenSpecimen application. +#' +#' @param response The API response object. +#' +#' @return A data table containing the parsed details of the site. +#' +#' @export +parse_site_details <- function(response) { + + # Extract the content from the response + mycontent2 <- content(response, "parsed") + + # Extract extension details + extension_details <- mycontent2$extensionDetail + + # Extract attribute details + attr_dp <- extension_details$attrs + + # Create clean column names + col_nms <- sapply(attr_dp, function(x) x$caption) %>% + janitor::make_clean_names() + + # Extract attribute values + values <- lapply(attr_dp, function(x) x$value) + + # Set names for values + names(values) <- col_nms + + # Convert values to data.table + dt1 = as.data.table(values) + + # Remove extension details from parsed content + mycontent2$extensionDetail <- NULL + mycontent2$coordinators <- NULL + # Convert remaining parsed content to data.table + mycontentdf <- mycontent2 %>% as.data.table() + + # Combine data.tables + mycontentdf <- cbind(mycontentdf, dt1) + + # Return the final data.table + mycontentdf + +} + +``` + + +```{r example-parse_site_details} +#parse_site_details() +``` + + +```{r tests-parse_site_details} +test_that("parse_site_details works", { + expect_true(inherits(parse_site_details, "function")) +}) +``` + + + +# get_os_site + +```{r function-get_os_site} +#' Get OpenSpecimen Site +#' +#' Use this function to retrieve details of a site from the OpenSpecimen application. +#' +#' @param auth_response Authentication response object obtained from the OpenSpecimen API. +#' @param site_id The unique identifier of the site to fetch. +#' +#' @return A data frame containing the details of the specified site. +#' +#' @export +get_os_site <- function(auth_response, site_id) { + + # Get the site details + # Specify the content type as JSON in the header + # Extract the authentication token from the response + auth_token <- auth_response$auth_response$token + url <- auth_response$url + + headers <- add_headers( + "Content-Type" = "application/json", + "X-OS-API-TOKEN" = auth_token + ) + + # Make the GET request for the query + response <- GET( + url = paste0(url, "/sites/", site_id), + config = headers, + encode = "json" + ) + + # Parse the response and return the results + results <- parse_os_response(response, + parse_data_function = "parse_site_details") + + # If inherits data.frame, return results, else return NULL + if (inherits(results, "data.frame")) { + return(results) + } else { + return(NULL) + } + +} + +``` + + +```{r example-get_os_site} +#get_os_site() +``` + + +```{r tests-get_os_site} +test_that("get_os_site works", { + expect_true(inherits(get_os_site, "function")) +}) +``` + +# get_bulk_site_details + +```{r function-get_bulk_site_details} +#' Get Bulk Site Details +#' +#' Use this function to retrieve details of multiple sites in bulk from the OpenSpecimen application. +#' +#' @param auth_response The authentication response object. +#' @param site_ids A vector of integers representing the IDs of the sites to retrieve details for. +#' @param ... Additional parameters to be passed to the underlying `get_os_site` function. +#' +#' @return A data table containing the details of the requested sites. +#' +#' @export +get_bulk_site_details <- function(auth_response, site_ids, ...) { + + # Check if site_ids is a vector of integers + if (isTRUE(any(round(site_ids) != site_ids))) { + stop("site_ids must be an integer") + } + + # Use tryCatch to handle errors + + list_dfs <- vector("list", length(site_ids)) + + for (i in seq_along(site_ids)) { + + list_dfs[[i]] <- tryCatch( + get_os_site(auth_response, site_id = site_ids[i], ...), + error = function(e) { + cli::cli_alert_warning(paste0("Error in site id: ", site_ids[i], " ", e$message)) + return(NULL) + } + ) + + if (i %% 10 == 0) { + cli::cli_alert_success( + paste0("Retrieved ", i, " sites", + " out of ", length(site_ids)) + ) + } + } + + ## Combine the list of data.tables into a single data.table + dt_final = data.table::rbindlist(list_dfs, fill = TRUE) + + cli::cli_alert_success(paste0("Done: Site details retrieved")) + + return(dt_final) + +} + +``` + +```{r example-get_bulk_site_details} +#get_bulk_site_details() +``` + +```{r tests-get_bulk_site_details} +test_that("get_bulk_site_details works", { + expect_true(inherits(get_bulk_site_details, "function")) +}) +``` + + ```{r development-inflate, eval=FALSE} # Run but keep eval=FALSE to avoid infinite loop # Execute in the console directly diff --git a/dev/config_fusen.yaml b/dev/config_fusen.yaml index 7814220..0355ed4 100644 --- a/dev/config_fusen.yaml +++ b/dev/config_fusen.yaml @@ -49,16 +49,19 @@ OpenSpecimenAPI.Rmd: - R/get_bulk_order_items.R - R/get_bulk_orders.R - R/get_bulk_query.R + - R/get_bulk_site_details.R - R/get_order_detail.R - R/get_order_items.R - R/get_orders.R - R/get_os_query.R + - R/get_os_site.R - R/parse_all_sites.R - R/parse_data.R - R/parse_order_detail_data.R - R/parse_os_oder_list.R - R/parse_os_order_data.R - R/parse_os_response.R + - R/parse_site_details.R - R/timestamp_to_date.R tests: - tests/testthat/test-auth_os.R @@ -77,6 +80,9 @@ OpenSpecimenAPI.Rmd: - tests/testthat/test-parse_all_sites.R - tests/testthat/test-get_bulk_order_items.R - tests/testthat/test-get_all_sites.R + - tests/testthat/test-parse_site_details.R + - tests/testthat/test-get_os_site.R + - tests/testthat/test-get_bulk_site_details.R vignettes: vignettes/open-specimen-api.Rmd inflate: flat_file: dev/OpenSpecimenAPI.Rmd diff --git a/man/get_bulk_site_details.Rd b/man/get_bulk_site_details.Rd new file mode 100644 index 0000000..44b4e86 --- /dev/null +++ b/man/get_bulk_site_details.Rd @@ -0,0 +1,24 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/get_bulk_site_details.R +\name{get_bulk_site_details} +\alias{get_bulk_site_details} +\title{Get Bulk Site Details} +\usage{ +get_bulk_site_details(auth_response, site_ids, ...) +} +\arguments{ +\item{auth_response}{The authentication response object.} + +\item{site_ids}{A vector of integers representing the IDs of the sites to retrieve details for.} + +\item{...}{Additional parameters to be passed to the underlying \code{get_os_site} function.} +} +\value{ +A data table containing the details of the requested sites. +} +\description{ +Use this function to retrieve details of multiple sites in bulk from the OpenSpecimen application. +} +\examples{ +#get_bulk_site_details() +} diff --git a/man/get_os_site.Rd b/man/get_os_site.Rd new file mode 100644 index 0000000..e83ed70 --- /dev/null +++ b/man/get_os_site.Rd @@ -0,0 +1,22 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/get_os_site.R +\name{get_os_site} +\alias{get_os_site} +\title{Get OpenSpecimen Site} +\usage{ +get_os_site(auth_response, site_id) +} +\arguments{ +\item{auth_response}{Authentication response object obtained from the OpenSpecimen API.} + +\item{site_id}{The unique identifier of the site to fetch.} +} +\value{ +A data frame containing the details of the specified site. +} +\description{ +Use this function to retrieve details of a site from the OpenSpecimen application. +} +\examples{ +#get_os_site() +} diff --git a/man/parse_site_details.Rd b/man/parse_site_details.Rd new file mode 100644 index 0000000..544cbc9 --- /dev/null +++ b/man/parse_site_details.Rd @@ -0,0 +1,20 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/parse_site_details.R +\name{parse_site_details} +\alias{parse_site_details} +\title{Parse OpenSpecimen Site Details} +\usage{ +parse_site_details(response) +} +\arguments{ +\item{response}{The API response object.} +} +\value{ +A data table containing the parsed details of the site. +} +\description{ +Use this function to parse the response and extract details of a site from the OpenSpecimen application. +} +\examples{ +#parse_site_details() +} diff --git a/tests/testthat/test-get_bulk_site_details.R b/tests/testthat/test-get_bulk_site_details.R new file mode 100644 index 0000000..eccc5d5 --- /dev/null +++ b/tests/testthat/test-get_bulk_site_details.R @@ -0,0 +1,5 @@ +# WARNING - Generated by {fusen} from dev/OpenSpecimenAPI.Rmd: do not edit by hand + +test_that("get_bulk_site_details works", { + expect_true(inherits(get_bulk_site_details, "function")) +}) diff --git a/tests/testthat/test-get_os_site.R b/tests/testthat/test-get_os_site.R new file mode 100644 index 0000000..f942b01 --- /dev/null +++ b/tests/testthat/test-get_os_site.R @@ -0,0 +1,5 @@ +# WARNING - Generated by {fusen} from dev/OpenSpecimenAPI.Rmd: do not edit by hand + +test_that("get_os_site works", { + expect_true(inherits(get_os_site, "function")) +}) diff --git a/tests/testthat/test-parse_site_details.R b/tests/testthat/test-parse_site_details.R new file mode 100644 index 0000000..4240530 --- /dev/null +++ b/tests/testthat/test-parse_site_details.R @@ -0,0 +1,5 @@ +# WARNING - Generated by {fusen} from dev/OpenSpecimenAPI.Rmd: do not edit by hand + +test_that("parse_site_details works", { + expect_true(inherits(parse_site_details, "function")) +}) diff --git a/vignettes/open-specimen-api.Rmd b/vignettes/open-specimen-api.Rmd index 74deb66..7c98163 100644 --- a/vignettes/open-specimen-api.Rmd +++ b/vignettes/open-specimen-api.Rmd @@ -171,3 +171,21 @@ df #get_all_sites() ``` +# parse_site_details + +```{r example-parse_site_details} +#parse_site_details() +``` + +# get_os_site + +```{r example-get_os_site} +#get_os_site() +``` + +# get_bulk_site_details + +```{r example-get_bulk_site_details} +#get_bulk_site_details() +``` +