Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

structure output functions; fix #48; fix #49 #51

Merged
merged 3 commits into from
Feb 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@ License: GPL (>= 3)
Depends:
R (>= 2.10)
Imports:
dplyr,
httr2,
tibble
tibble,
tidyr
Suggests:
covr,
httpuv,
Expand Down
6 changes: 6 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,15 @@ export(icd_get_releases)
export(icd_oauth_client)
export(icd_search_foundation)
export(icd_structure_foundation)
export(icd_structure_search)
importFrom(dplyr,bind_cols)
importFrom(dplyr,bind_rows)
importFrom(httr2,oauth_client)
importFrom(httr2,req_headers)
importFrom(httr2,req_oauth_client_credentials)
importFrom(httr2,req_perform)
importFrom(httr2,req_url_query)
importFrom(httr2,request)
importFrom(httr2,resp_body_json)
importFrom(tibble,tibble)
importFrom(tidyr,unnest)
5 changes: 4 additions & 1 deletion R/codigo.R
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
#' @keywords internal
#' @name codigo
#' @importFrom httr2 oauth_client request req_url_query req_headers
#' req_oauth_client_credentials req_perform
#' req_oauth_client_credentials req_perform resp_body_json
#' @importFrom tibble tibble
#' @importFrom dplyr bind_cols bind_rows
#' @importFrom tidyr unnest
#'
"_PACKAGE"
81 changes: 31 additions & 50 deletions R/icd_get.R
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
#'
#' Get information on various ICD 11 Foundation entities
#'
#' @param base_url The base URL of the API. Default uses the WHO API server at
#' https://id.who.int. If you are using a locally deployed server or hosting
#' your own ICD API server, you should specify the URL of your instance here.
#' @param client The OAuth2 client produced through a call to `icd_oauth_client()`.
#' @param scope Scopes to be requested from the resource owner. Default is
#' *"icdapi_access"* as specified in the ICD API documentation.
#' @param id Unique numerical identifier for an entity.
#' @param release A string specifying the release version of the Foundation to
#' search from. If not specified, defaults to the latest release version. See
Expand All @@ -23,11 +17,17 @@
#' the translations of ICD-11 completes. The values are language codes such as
#' en, es, zh, etc. Depending on the `release_id` specified, the available
#' languages will vary. Default is English ("en").
#' @param parse Logical. Should JSON response body be parsed? Default is
#' TRUE. If FALSE, response body is kept as raw JSON.
#' @param tabular Logical. Should output be structured into a tibble? Default
#' to TRUE.
#' @param base_url The base URL of the API. Default uses the WHO API server at
#' https://id.who.int. If you are using a locally deployed server or hosting
#' your own ICD API server, you should specify the URL of your instance here.
#' @param client The OAuth2 client produced through a call to `icd_oauth_client()`.
#' @param scope Scopes to be requested from the resource owner. Default is
#' *"icdapi_access"* as specified in the ICD API documentation.
#'
#' @return A list or JSON (depending on `parse`) with information on specified
#' ICD 11 Foundation and top level entities
#' @return A list with information on specified ICD 11 Foundation and top level
#' entities.
#'
#' @examples
#' icd_get_foundation()
Expand All @@ -38,13 +38,13 @@
#' @rdname icd_get
#' @export
#'
icd_get_foundation <- function(base_url = "https://id.who.int",
client = icd_oauth_client(),
scope = "icdapi_access",
release = NULL,
icd_get_foundation <- function(release = NULL,
api_version = c("v2", "v1"),
language = "en",
parse = TRUE) {
tabular = TRUE,
base_url = "https://id.who.int",
client = icd_oauth_client(),
scope = "icdapi_access") {
## Get API version to use ----
api_version <- match.arg(api_version)

Expand All @@ -55,46 +55,38 @@ icd_get_foundation <- function(base_url = "https://id.who.int",
if (!is.null(language)) icd_check_language(release, language)

## Make request ----
req <- httr2::request(file.path(base_url, "icd/entity")) |>
resp <- httr2::request(file.path(base_url, "icd/entity")) |>
httr2::req_headers(
Accept = "application/json",
"API-Version" = api_version,
"Accept-Language" = language
) |>
## Authenticate ----
## Authenticate and perform request ----
icd_authenticate(client = client, scope = scope) |>
## Perform request ----
httr2::req_perform()
httr2::req_perform() |>
httr2::resp_body_json()

## Determine what output to return ----
if (parse) {
### Parse JSON and simplify ----
resp <- req |>
httr2::resp_body_json()
if (tabular) {
icd_structure_foundation(resp)
} else {
### Keep as JSON ----
resp <- req |>
httr2::resp_body_raw()
resp
}

## Return response body ----
resp
}


#'
#' @rdname icd_get
#' @export
#'
icd_get_entity <- function(base_url = "https://id.who.int",
client = icd_oauth_client(),
scope = "icdapi_access",
id,
icd_get_entity <- function(id,
release = NULL,
include = NULL,
api_version = c("v2", "v1"),
language = "en",
parse = TRUE) {
base_url = "https://id.who.int",
client = icd_oauth_client(),
scope = "icdapi_access") {
## Get API version to use ----
api_version <- match.arg(api_version)

Expand Down Expand Up @@ -128,23 +120,12 @@ icd_get_entity <- function(base_url = "https://id.who.int",
httr2::req_url_query(include = include)
}

## Authenticate request ----
req <- req |>
## Authenticate and perform request ----
resp <- req |>
icd_authenticate(client = client, scope = "icdapi_access") |>
## Perform request ----
httr2::req_perform()

## Determine what output to return ----
if (parse) {
### Parse JSON and simplify ----
resp <- req |>
httr2::resp_body_json()
} else {
### Keep as JSON ----
resp <- req |>
httr2::resp_body_raw()
}
httr2::req_perform() |>
httr2::resp_body_json()

## Return response body ----
## Return response ----
resp
}
51 changes: 22 additions & 29 deletions R/icd_search.R
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
#'
#' Search the foundation component of the ICD-11
#'
#' @param base_url The base URL of the API. Default uses the WHO API server at
#' https://id.who.int. If you are using a locally deployed server or hosting
#' your own ICD API server, you should specify the URL of your instance here.
#' @param client The OAuth2 client produced through a call to `icd_oauth_client()`.
#' @param scope Scopes to be requested from the resource owner. Default is
#' *"icdapi_access"* as specified in the ICD API documentation.
#' @param q String. Text to be searched. Having the character `%` at the end will
#' be regarded as a wild card for that word.
#' @param subtree A string or vector of strings of URIs. If provided, the
Expand Down Expand Up @@ -46,22 +40,25 @@
#' the translations of ICD-11 completes. The values are language codes such as
#' en, es, zh, etc. Depending on the `release_id` specified, the available
#' languages will vary. Default is English ("en").
#' @param parse Logical. Should JSON response body be parsed? Default is
#' TRUE. If FALSE, response body is kept as raw JSON.
#' @param tabular Logical. Should output be structured into a tibble? Default
#' to TRUE.
#' @param base_url The base URL of the API. Default uses the WHO API server at
#' https://id.who.int. If you are using a locally deployed server or hosting
#' your own ICD API server, you should specify the URL of your instance here.
#' @param client The OAuth2 client produced through a call to `icd_oauth_client()`.
#' @param scope Scopes to be requested from the resource owner. Default is
#' *"icdapi_access"* as specified in the ICD API documentation.
#'
#' @return An `httr2_response` object
#' @return A tibble of search results.
#'
#' @examples
#' icd_search_foundation(q = "colorectal cancer")
#' icd_search_foundation("colorectal cancer")
#'
#' @rdname icd_search
#' @export
#'

icd_search_foundation <- function(base_url = "https://id.who.int",
client = icd_oauth_client(),
scope = "icdapi_access",
q,
icd_search_foundation <- function(q,
subtree = NULL,
chapter = NULL,
flexisearch = FALSE,
Expand All @@ -71,7 +68,10 @@ icd_search_foundation <- function(base_url = "https://id.who.int",
highlight = FALSE,
api_version = c("v2", "v1"),
language = "en",
parse = TRUE) {
tabular = TRUE,
base_url = "https://id.who.int",
client = icd_oauth_client(),
scope = "icdapi_access") {
## Get API version to use ----
api_version <- match.arg(api_version)

Expand Down Expand Up @@ -126,30 +126,23 @@ icd_search_foundation <- function(base_url = "https://id.who.int",
highlightingEnabled = ifelse(highlight, "true", "false")
)

## Add headers ----
req <- req |>
## Add headers, authenticate, and perform request ----
resp <- req |>
httr2::req_headers(
Accept = "application/json",
"API-Version" = api_version,
"Accept-Language" = language
) |>
## Authenticate ----
icd_authenticate(client = client, scope = scope) |>
## Perform request ----
httr2::req_perform()
httr2::req_perform() |>
httr2::resp_body_json()

## Determine what output to return ----
if (parse) {
## Structure JSON response ----
resp <- httr2::resp_body_json(req)
if (tabular) {
icd_structure_search(resp)
} else {
### Keep as JSON ----
resp <- req |>
httr2::resp_body_raw()
resp
}

## Return response body ----
resp
}


81 changes: 70 additions & 11 deletions R/icd_structure.R
Original file line number Diff line number Diff line change
@@ -1,22 +1,28 @@
#'
#' Structure ICD list outputs
#' Structure ICD list and ICD search outputs
#'
#' @param icd_list An `icd_list` object produced by a call to any of the `icd_get`
#' functions
#' @param icd_list An `icd_list` object produced by a call to any of the
#' `icd_get` functions
#' @param icd_search An `icd_search` object produced by a call to any of the
#' `icd_search` functions
#'
#' @return An object of class `icd_tbl` which is basically a `data.frame` format
#' of ICD outputs
#' @return A tibble of structured ICD outputs.
#'
#' @details These functions are meant to be helper functions and are used
#' within the `icd_get` and `icd_search` functions to structure the output
#' responses.
#'
#' @examples
#' icd_list <- icd_get_foundation()
#' icd_list <- icd_get_foundation(tabular = FALSE)
#' icd_tbl_foundation <- icd_structure_foundation(icd_list)
#' icd_structure_search(icd_search_foundation("cholera", tabular = FALSE))
#'
#' @rdname icd_structure
#' @export
#'
icd_structure_foundation <- function(icd_list) {
## Structure title ----
icd_list$title <- do.call(cbind, icd_list$title) |> data.frame()
icd_list$title <- dplyr::bind_cols(icd_list$title)

## Structure availableLanguages ----
icd_list$availableLanguages <- unlist(icd_list$availableLanguages) |>
Expand All @@ -26,13 +32,66 @@ icd_structure_foundation <- function(icd_list) {
icd_list$child <- unlist(icd_list$child) |> list()

## Bind columns and rename columns ----
icd_tbl <- do.call(cbind, icd_list)
icd_tbl <- dplyr::bind_cols(icd_list)
names(icd_tbl)[3] <- "title@language"
names(icd_tbl)[4] <- "title@value"
names(icd_tbl)[8] <- "child"

## Create `icd_tbl` class object ----
class(icd_tbl) <- "icd_tbl"

## Return output ----
icd_tbl
}

#'
#' @rdname icd_structure
#' @export
#'

icd_structure_search <- function(icd_search) {
## Process search metadata ----
meta <- lapply(
X = icd_search[1:7],
FUN = function(x) ifelse(is.null(x), NA, x)
) |>
dplyr::bind_cols()

## Standardise classes of metadata fields ----
meta <- within(
meta,
{
error <- ifelse(is.logical(error), error, as.logical(error))
errorMessage <- ifelse(
is.character(errorMessage), errorMessage, as.character(errorMessage)
)
resultChopped <- ifelse(
is.logical(resultChopped), resultChopped, as.logical(resultChopped)
)
wordSuggestionsChopped <- ifelse(
is.logical(wordSuggestionsChopped),
wordSuggestionsChopped,
as.logical(wordSuggestionsChopped)
)
guessType <- ifelse(is.integer(guessType), guessType, as.integer(guessType))
uniqueSearchId <- ifelse(
is.character(uniqueSearchId), uniqueSearchId, as.character(uniqueSearchId)
)
words <- ifelse(is.character(words), words, as.character(words))
}
)

## Process search results ----
search_results <- lapply(
X = icd_search$destinationEntities,
FUN = function(x) do.call(cbind, x) |>
data.frame() |>
tidyr::unnest(cols = dplyr::everything())
) |>
dplyr::bind_rows()

## Set attributes for search metadata ----
attributes(search_results)$metadata <- meta

## Return search results
search_results
}


Loading