Title: | Handling HL7 FHIR® Resources in R |
---|---|
Description: | Useful tools for conveniently downloading FHIR resources in xml format and converting them to R data.frames. The package uses FHIR-search to download bundles from a FHIR server, provides functions to save and read xml-files containing such bundles and allows flattening the bundles to data.frames using XPath expressions. FHIR® is the registered trademark of HL7 and is used with the permission of HL7. Use of the FHIR trademark does not constitute endorsement of this product by HL7. |
Authors: | Thomas Peschel [aut],
Julia Palm [aut, cre] |
Maintainer: | Julia Palm <[email protected]> |
License: | GPL-3 |
Version: | 2.2.0.9003 |
Built: | 2025-03-05 13:54:59 UTC |
Source: | https://github.com/polar-fhir/fhircrackr |
Tries to convert a character vector containing xml strings representing FHIR bundles to an object of class fhir_bundle_list.
as_fhir(x)
as_fhir(x)
x |
A character vector where each element is a string representing an xml FHIR bundle. |
#character vector containing fhir bundles bundle_strings <- c( "<Bundle> <type value='searchset'/> <entry> <resource> <Patient> <id value='id1'/> <name> <given value='Marie'/> </name> </Patient> </resource> </entry> </Bundle>", "<Bundle> <type value='searchset'/> <entry> <resource> <Patient> <id value='id2'/> <name> <given value='Max'/> </name> </Patient> </resource> </entry> </Bundle>" ) #convert to FHIR bundle list bundles <- as_fhir(bundle_strings)
#character vector containing fhir bundles bundle_strings <- c( "<Bundle> <type value='searchset'/> <entry> <resource> <Patient> <id value='id1'/> <name> <given value='Marie'/> </name> </Patient> </resource> </entry> </Bundle>", "<Bundle> <type value='searchset'/> <entry> <resource> <Patient> <id value='id2'/> <name> <given value='Max'/> </name> </Patient> </resource> </entry> </Bundle>" ) #convert to FHIR bundle list bundles <- as_fhir(bundle_strings)
These data examples are bundles that contain very few, very simple resources that have multiple entries and can be used for demonstration purposes. See Source for how the xml versions look.
example_bundles1 example_bundles2 example_bundles3 example_bundles4 example_bundles5 example_bundles6 example_bundles7 example_bundles_empty
example_bundles1 example_bundles2 example_bundles3 example_bundles4 example_bundles5 example_bundles6 example_bundles7 example_bundles_empty
An object of class fhir_bundle_list
of length 1.
An object of class fhir_bundle_list
of length 1.
An object of class fhir_bundle_list
of length 1.
An object of class fhir_bundle_list
of length 1.
An object of class fhir_bundle_list
of length 1.
An object of class fhir_bundle_list
of length 1.
An object of class fhir_bundle_list
of length 1.
An object of class fhir_bundle_list
of length 1.
example_bundles1
contains 1 bundle with 2 Patient resources.
example_bundles2
contains 1 bundle with 3 Patient resources.
example_bundles3
contains 1 bundle with 3 Patient resources and 1 Observation resource.
example_bundles4
contains 1 bundle with 2 Medication resources, one of which has some @id
xml attributes
example_bundles5
contains 1 bundle with 2 Observation resources.
example_bundles6
contains 1 bundle with 2 Patient resources.
example_bundles7
contains 1 bundle with 2 Patient resources.
example_bundles_empty
contains one empty bundle.
example_bundles1
<Bundle> <type value='searchset'/> <entry> <resource> <Patient> <id value='id1'/> <address> <use value='home'/> <city value='Amsterdam'/> <type value='physical'/> <country value='Netherlands'/> </address> <name> <given value='Marie'/> </name> </Patient> </resource> </entry> <entry> <resource> <Patient> <id value='id3'/> <address> <use value='home'/> <city value='Berlin'/> </address> <address> <type value='postal'/> <country value='France'/> </address> <address> <use value='work'/> <city value='London'/> <type value='postal'/> <country value='England'/> </address> <name> <given value='Frank'/> </name> <name> <given value='Max'/> </name> </Patient> </resource> </entry> </Bundle>
example_bundles2
<Bundle> <type value='searchset'/> <entry> <resource> <Patient> <id value='id1'/> <address> <use value='home'/> <city value='Amsterdam'/> <type value='physical'/> <country value='Netherlands'/> </address> <name> <given value='Marie'/> </name> </Patient> </resource> </entry> <entry> <resource> <Patient> <id value='id2'/> <address> <use value='home'/> <city value='Rome'/> <type value='physical'/> <country value='Italy'/> </address> <address> <use value='work'/> <city value='Stockholm'/> <type value='postal'/> <country value='Sweden'/> </address> <name> <given value='Susie'/> </name> </Patient> </resource> </entry> <entry> <resource> <Patient> <id value='id3'/> <address> <use value='home'/> <city value='Berlin'/> </address> <address> <type value='postal'/> <country value='France'/> </address> <address> <use value='work'/> <city value='London'/> <type value='postal'/> <country value='England'/> </address> <name> <given value='Frank'/> </name> <name> <given value='Max'/> </name> </Patient> </resource> </entry> </Bundle>
example_bundles3
<Bundle> <type value='searchset'/> <entry> <resource> <Patient> <id value='id1'/> <address> <use value='home'/> <city value='Amsterdam'/> <type value='physical'/> <country value='Netherlands'/> </address> <name> <given value='Marie'/> </name> </Patient> </resource> </entry> <entry> <resource> <Patient> <id value='id2'/> <address> <use value='home'/> <city value='Rome'/> <type value='physical'/> <country value='Italy'/> </address> <address> <use value='work'/> <city value='Stockholm'/> <type value='postal'/> <country value='Sweden'/> </address> <name> <given value='Susie'/> </name> </Patient> </resource> </entry> <entry> <resource> <Patient> <id value='id3'/> <address> <use value='home'/> <city value='Berlin'/> </address> <address> <type value='postal'/> <country value='France'/> </address> <address> <use value='work'/> <city value='London'/> <type value='postal'/> <country value='England'/> </address> <name> <given value='Frank'/> </name> <name> <given value='Max'/> </name> </Patient> <resource/> </entry> <entry> <resource> <Observation> <id value = 'obs1'/> <code> <coding> <system value='http://loinc.org'/> <code value='29463-7'/> <display value='Body Weight'/> </coding> <coding> <system value='http://snomed.info/sct'/> <code value='27113001'/> <display value='Body weight'/> </coding> </code> <subject> <reference value='Patient/id3'/> </subject> </Observation> </resource> </entry> </Bundle>"
example_bundles4
<Bundle> <type value='searchset'/> <entry> <resource> <Medication> <id value='1285'/> <code> <coding> <system value='http://www.nlm.nih.gov/research/umls/rxnorm'/> <code value='1594660'/> <display value='Alemtuzumab 10mg/ml (Lemtrada)'/> </coding> </code> <ingredient id='1'> <itemReference> <reference value='Substance/5463'/> </itemReference> </ingredient> <ingredient id='2'> <itemReference> <reference value='Substance/3401'/> </itemReference> </ingredient> </Medication> </resource> </entry> <entry> <resource> <Medication> <id value='45226'/> <code> <coding> <system value='http://snomed.info/sct'/> <code value='373994007'/> <display value='Prednisone 5mg tablet (Product)'/> </coding> <text value='Prednisone 5mg tablet (Product)'/> </code> <ingredient id='1'> <itemReference> <reference value='Substance/6912'/> </itemReference> </ingredient> <ingredient id='2'> <itemReference> <reference value='Substance/3710'/> </itemReference> </ingredient> </Medication> </resource> </entry> </Bundle>
example_bundles5
<Bundle> <type value='searchset'/> <entry> <resource> <Observation> <id value = 'obs1'/> <code> <coding> <system value='http://loinc.org'/> <code value='29463-7'/> <display value='Body Weight'/> </coding> <coding> <system value='http://snomed.info/sct'/> <code value='27113001'/> <display value='Body weight'/> </coding> </code> <subject> <reference value='Patient/id3'/> </subject> </Observation> </resource> </entry> <entry> <resource> <Observation> <id value = 'obs2'/> <code> <coding> <system value='http://loinc.org'/> <code value='8302-2'/> <display value='Body Height'/> </coding> <coding> <system value='http://snomed.info/sct'/> <code value='50373000'/> <display value='Body height measure'/> </coding> </code> <subject> <reference value='Patient/id3'/> </subject> </Observation> </resource> </entry> </Bundle>"
example_bundles6
"<Bundle> <type value='searchset'/> <entry> <resource> <Patient> <id value='id1'/> <address> <line value='Example Street 1'/> <line value='c/o Baker'/> <city value = 'London'/> <use value = 'home'/> </address> <address> <line value = 'Some firm'/> <line value = 'Some Department'/> <line value = 'Some Lane 1'/> <city value = 'London'/> <use value = 'work'/> </address> </Patient> </resource> </entry> <entry> <resource> <Patient> <id value='id2'/> <address> <line value='Rue example 3'/> <city value = 'Paris'/> <use value = 'home'/> </address> <address> <line value = 'La fabrique'/> <line value = 'Avenue 33'/> <city value = 'Paris'/> <use value = 'work'/> </address> </Patient> </resource> </entry> </Bundle>"
example_bundles7
"<Bundle> <type value='searchset'/> <entry> <resource> <Patient> <id value='id1'/> <name> <given value='Marie'/> <given value='Luise'/> <family value = 'Smith'/> <use value = 'official'/> </name> <name> <given value = 'Lea'/> <given value = 'Sophie'/> <given value = 'Anna'/> <family value = 'Baker'/> <use value = 'nickname'/> </name> </Patient> </resource> </entry> <entry> <resource> <Patient> <id value='id2'/> <name> <given value='Max'/> <family value = 'Brown'/> <use value = 'official'/> </name> <name> <given value = 'Anton'/> <given value = 'John'/> <family value = 'Jones'/> <use value = 'nickname'/> </name> </Patient> </resource> </entry> </Bundle>"
example_bundles_empty
<Bundle> <id value="c9edcd82-092c-4f63-8c8d-fdfd03e38d64"/> <meta> <versionId value="23558aa5-aeba-4145-89a3-195bb6ec5401"/> <lastUpdated value="2024-11-19T13:43:34.556+00:00"/> </meta> <type value="searchset"/> <timestamp value="2024-11-19T13:43:34.556+00:00"/> <total value="0"/> <link> <relation value="self"/> <url value="https://server.fire.ly/Patient?gender=bla&_total=accurate&_count=0&_skip=0"/> </link> </Bundle>
#unserialize xml objects before doing anything else with them! fhir_unserialize(bundles = example_bundles1) #unserialize xml objects before doing anything else with them! fhir_unserialize(bundles = example_bundles2) #unserialize xml objects before doing anything else with them! fhir_unserialize(bundles = example_bundles3) #unserialize xml objects before doing anything else with them! fhir_unserialize(bundles = example_bundles4) #unserialize xml objects before doing anything else with them! fhir_unserialize(bundles = example_bundles5) #unserialize xml objects before doing anything else with them! fhir_unserialize(bundles = example_bundles6) #unserialize xml objects before doing anything else with them! fhir_unserialize(bundles = example_bundles7) #unserialize xml objects before doing anything else with them! fhir_unserialize(bundles = example_bundles_empty)
#unserialize xml objects before doing anything else with them! fhir_unserialize(bundles = example_bundles1) #unserialize xml objects before doing anything else with them! fhir_unserialize(bundles = example_bundles2) #unserialize xml objects before doing anything else with them! fhir_unserialize(bundles = example_bundles3) #unserialize xml objects before doing anything else with them! fhir_unserialize(bundles = example_bundles4) #unserialize xml objects before doing anything else with them! fhir_unserialize(bundles = example_bundles5) #unserialize xml objects before doing anything else with them! fhir_unserialize(bundles = example_bundles6) #unserialize xml objects before doing anything else with them! fhir_unserialize(bundles = example_bundles7) #unserialize xml objects before doing anything else with them! fhir_unserialize(bundles = example_bundles_empty)
This function is a wrapper to create an httr::Token object for authentication with OAuth2/OpenID Connect.
Internally, it calls httr::oauth_app()
, httr::oauth_endpoint()
and httr::oauth2.0_token()
to create a token that can
then be used in fhir_search.
fhir_authenticate( secret, key, base_url, access, authorize, query_authorize_extra = list() )
fhir_authenticate( secret, key, base_url, access, authorize, query_authorize_extra = list() )
secret |
The consumer/client secret, belonging to |
key |
Consumer key, also called client ID. For Keycloak this would for instance be the Keycloak client, e.g. "postman". |
base_url |
The URL the user will be redirected to after authorization is complete. This will usually be the base url of you FHIR server. |
access |
The url used to exchange unauthenticated for authenticated token.
This can be identical to |
authorize |
The url to send the client for authorization. |
query_authorize_extra |
A named list holding query parameters to append to initial auth page query. Could hold info about user identity and scope for keycloak like this: list(scope = "openid", grant_type = "password", username = "fhir-user", password = "fhirtest") |
Create fhir_body object
fhir_body(content, type) ## S4 method for signature 'list,missing' fhir_body(content) ## S4 method for signature 'list,character' fhir_body(content, type) ## S4 method for signature 'character,character' fhir_body(content, type)
fhir_body(content, type) ## S4 method for signature 'list,missing' fhir_body(content) ## S4 method for signature 'list,character' fhir_body(content, type) ## S4 method for signature 'character,character' fhir_body(content, type)
content |
A character vector of length one representing the body for the post in the format specified in |
type |
A string defining the type of the body e.g. |
An object of type fhir_body.
#body that could be used in a FHIR search request POSTed to an URL like baseurl/Patient/_search fhir_body(content = "gender=female&_summary=count", type="application/x-www-form-urlencoded") fhir_body(content = list("gender" = "female", "_summary" = "count"))
#body that could be used in a FHIR search request POSTed to an URL like baseurl/Patient/_search fhir_body(content = "gender=female&_summary=count", type="application/x-www-form-urlencoded") fhir_body(content = list("gender" = "female", "_summary" = "count"))
Objects of this class should always be created with a call to the function fhir_body()
content
A vector of length one representing the body for the post.
type
A vector of length one defining the type of the body e.g. "application/x-www-form-urlencoded"
or "xml"
.
This function takes a table as produced by fhir_crack()
with format="wide"
and builds a fhir_bundle_xml object from it. It is primarily used
to create transaction/batch bundles to POST back to a FHIR server. The column names of the table must represent the XPath expression of the
respective element with indices for repeating items. A table like this is produced when FHIR resources have been cracked with fhir_crack()
without
assigning explicit column names in the fhir_design/fhir_table_description and the format has been set to "wide"
.
fhir_build_bundle( table, brackets, resource_type, bundle_type = "transaction", verbose = 1 ) ## S4 method for signature 'data.frame' fhir_build_bundle( table, brackets, resource_type, bundle_type = "transaction", verbose = 1 ) ## S4 method for signature 'list' fhir_build_bundle(table, brackets, bundle_type = "transaction", verbose = 1)
fhir_build_bundle( table, brackets, resource_type, bundle_type = "transaction", verbose = 1 ) ## S4 method for signature 'data.frame' fhir_build_bundle( table, brackets, resource_type, bundle_type = "transaction", verbose = 1 ) ## S4 method for signature 'list' fhir_build_bundle(table, brackets, bundle_type = "transaction", verbose = 1)
table |
A wide table as produced by |
brackets |
A character vector of length one. The brackets used for cracking. |
resource_type |
A character vector of length one or fhir_resource_type object
indicating which resource type is represented in the table, if a single table is provided. This argument is
ignored when |
bundle_type |
A character vector of length one defining the bundle type. Will usually be
either |
verbose |
An integer vector of length one. If 0, nothing is printed, if > 0 progress message is printed. Defaults to 1. |
The typical use case would look like this:
Download resources from a server with fhir_search()
Crack to wide format them with fhir_crack()
Do something to values (e.g. some kind of anonymization)
Translate the data back into FHIR resources with fhir_build_bundle()
Post the resources to a server
A FHIR bundle that can be POSTed to a server is usually of type transaction
or batch
. Each entry of these bundles consists of the resource itself
as well as an instruction for the server of what to to with the resource. A very simple example looks like this:
<Bundle> <type value="transaction"/> <entry> <resource> <Patient> <id value="id1"/> <address> <city value="Amsterdam"/> <country value="Netherlands"/> </address> <name> <given value="Marie"/> </name> </Patient> </resource> <request> <method value="POST"/> <url value="Patient"/> </request> </entry> <entry> <resource> <Patient> <id value="id2"/> <address> <city value="Paris"/> <country value="France"/> </address> <name> <given value="Anne"/> </name> </Patient> </resource> <request> <method value="POST"/> <url value="Patient"/> </request> </entry> </Bundle>
In this example the bundle contains two Patient resources that are sent to server with a POST. For more information the structure of transaction/batch bundles, please see the FHIR documentation at https://www.hl7.org/fhir/http.html and https://www.hl7.org/fhir/bundle.html.
In the table, each row corresponds to one resource that is created. To add the information for the request
element of the bundle,
this table has to be augmented with two columns named request.method
and request.url
, which contain the respective HTTP verb and URL for the resource.
If these columns are not added to the table, fhir_build_bundle()
still builds bundles from it, but those bundles will not be POSTable to a server. See examples.
A fhir_bundle_xml object.
fhir_crack()
,fhir_cast()
, fhir_build_resource()
, fhir_post()
#unserialize example bundles <- fhir_unserialize(bundles = example_bundles1) #crack fhir resources table_desc_pat <- fhir_table_description( resource = "Patient", brackets = c("[", "]"), sep = " ", format = "wide" ) df <- fhir_crack(bundles = bundles, design = table_desc_pat) #add request info to table request <- data.frame( request.method = c("POST", "PUT"), request.url = c("Patient", "Patient/id3") ) request_df <- cbind(df, request) #build bundle bundle <- fhir_build_bundle(table = request_df, brackets = table_desc_pat@brackets, resource_type = "Patient", bundle_type = "transaction") #print to console cat(toString(bundle))
#unserialize example bundles <- fhir_unserialize(bundles = example_bundles1) #crack fhir resources table_desc_pat <- fhir_table_description( resource = "Patient", brackets = c("[", "]"), sep = " ", format = "wide" ) df <- fhir_crack(bundles = bundles, design = table_desc_pat) #add request info to table request <- data.frame( request.method = c("POST", "PUT"), request.url = c("Patient", "Patient/id3") ) request_df <- cbind(df, request) #build bundle bundle <- fhir_build_bundle(table = request_df, brackets = table_desc_pat@brackets, resource_type = "Patient", bundle_type = "transaction") #print to console cat(toString(bundle))
This function takes a single row from a wide table as produced by fhir_crack()
and builds a fhir_resource_xml object from it. The column names of the table
must represent the XPath expression of the respective element with indices for repeating items. A table like this is produced when FHIR resources have
been cracked with fhir_crack()
without assigning explicit column names in the fhir_design/fhir_table_description and with format
set to "wide"
.
fhir_build_resource(row, brackets, resource_type)
fhir_build_resource(row, brackets, resource_type)
row |
Single row from a wide table as produced by |
brackets |
A character vector of length one. The brackets used for cracking. |
resource_type |
A character vector of length one or fhir_resource_type object indicating which resource type the table is build from. |
A fhir_resource_xml object.
fhir_cast()
, fhir_crack()
, fhir_build_bundle()
, fhir_post()
, fhir_put()
#unserialize example bundles <- fhir_unserialize(bundles = example_bundles1) #crack fhir resources Pat <- fhir_table_description( resource = "Patient", brackets = c("[", "]"), sep = " ", format = "wide" ) df <- fhir_crack(bundles = bundles, design = Pat) #build resource resource <- fhir_build_resource( row = df[1,], brackets = c('[', ']'), resource_type = "Patient" ) #print to console resource
#unserialize example bundles <- fhir_unserialize(bundles = example_bundles1) #crack fhir resources Pat <- fhir_table_description( resource = "Patient", brackets = c("[", "]"), sep = " ", format = "wide" ) df <- fhir_crack(bundles = bundles, design = Pat) #build resource resource <- fhir_build_resource( row = df[1,], brackets = c('[', ']'), resource_type = "Patient" ) #print to console resource
A fhir_bundle_list is a list of fhir_bundle_xml or fhir_bundle_serialized objects. It is
usually returned by a call to fhir_search()
.
fhir_bundle_list(bundles)
fhir_bundle_list(bundles)
bundles |
A list of xml_nodes/fhir_bundle_xml objects or of raw/fhir_bundle_serialized objects |
The only scenario where one would use this constructor function is when several fhir_bundle or fhir_bundle_list objects should be merged into one big fhir_bundle_list before cracking (see examples).
#unserialize example bundles bundles1 <- fhir_unserialize(example_bundles1) bundles2 <- fhir_unserialize(example_bundles2) #bind them together in one fhir_bundle_list bound_bundles <- fhir_bundle_list(c(bundles1, bundles2)) class(bound_bundles) #bound list contains bundles from both original lists length(bundles1) length(bundles2) length(bound_bundles) #Create fhir_bundle list from xml objects b1 <- xml2::read_xml("<Bundle><Resource><item value='1'/></Resource></Bundle>") b2 <- xml2::read_xml("<Bundle><Resource><item value='2'/></Resource></Bundle>") fhir_bundle_list(bundles = list(b1, b2)) fhir_bundle_list(bundles = list(fhir_bundle_xml(b1), fhir_bundle_xml(b2))) r1 <- xml2::xml_serialize(object = b1, connection= NULL) r2 <- xml2::xml_serialize(object = b2, connection= NULL) fhir_bundle_list(bundles = list(r1, r2))
#unserialize example bundles bundles1 <- fhir_unserialize(example_bundles1) bundles2 <- fhir_unserialize(example_bundles2) #bind them together in one fhir_bundle_list bound_bundles <- fhir_bundle_list(c(bundles1, bundles2)) class(bound_bundles) #bound list contains bundles from both original lists length(bundles1) length(bundles2) length(bound_bundles) #Create fhir_bundle list from xml objects b1 <- xml2::read_xml("<Bundle><Resource><item value='1'/></Resource></Bundle>") b2 <- xml2::read_xml("<Bundle><Resource><item value='2'/></Resource></Bundle>") fhir_bundle_list(bundles = list(b1, b2)) fhir_bundle_list(bundles = list(fhir_bundle_xml(b1), fhir_bundle_xml(b2))) r1 <- xml2::xml_serialize(object = b1, connection= NULL) r2 <- xml2::xml_serialize(object = b2, connection= NULL) fhir_bundle_list(bundles = list(r1, r2))
A fhir_bundle_list is a list of fhir_bundle_xml or fhir_bundle_serialized objects. It should
not be created by the user but returned by a call to fhir_search()
.
A fhir_bundle_serialized
is a fhir_bundle_xml
that has been serialized using fhir_serialize()
. In this form, the
bundle cannot be used in any meaningful way, but it can be saved and loaded as an .RData
or .rds
object without breaking the
external pointers in the xml. See ?fhir_serialize
and ?fhir_unserialize
.
This should only be used if you want to create small examples. Usually, a fhir_bundle_xml
will
be returned by fhir_search()
.
fhir_bundle_xml(bundle)
fhir_bundle_xml(bundle)
bundle |
A xml-object representing a FHIR bundle |
fhir_bundle_xml(bundle = xml2::xml_unserialize(patient_bundles[[1]]))
fhir_bundle_xml(bundle = xml2::xml_unserialize(patient_bundles[[1]]))
A fhir_bundle_xml
is an xml representation of a FHIR bundle (https://www.hl7.org/fhir/bundle.html).
It is usually found inside a fhir_bundle_list
which is returned by a call to fhir_search()
.
next_link
A fhir_url pointing to the next bundle on the server.
self_link
A fhir_url pointing to this bundle on the server.
Returns the fhir_design of the last call to fhir_crack()
.
fhir_canonical_design()
fhir_canonical_design()
fhir_design()
, fhir_table_description()
#load example bundles bundles <- fhir_unserialize(bundles = patient_bundles) #define design patients <- fhir_table_description(resource = 'Patient') design <- fhir_design(patients) result <- fhir_crack(bundles = bundles, design = design) fhir_canonical_design()
#load example bundles bundles <- fhir_unserialize(bundles = patient_bundles) #define design patients <- fhir_table_description(resource = 'Patient') design <- fhir_design(patients) result <- fhir_crack(bundles = bundles, design = design) fhir_canonical_design()
Get the capability statement of a FHIR server.
This function downloads a capability statement and creates three data.frames from it:
Meta
contains general information on the server
Rest
contains information on the Rest operations the server supports
Resources
contains information on the supported resource types
When there is more than one piece of information regarding a variable in these data.frames,
they are divided by the string specified in sep
. If brackets
is not NULL, those entries
will also be assigned indices so you can melt them using fhir_melt()
.
fhir_capability_statement( url = "https://hapi.fhir.org/baseR4", username = NULL, password = NULL, token = NULL, add_headers = NULL, brackets = NULL, sep = " ::: ", log_errors = NULL, verbose = deprecated() )
fhir_capability_statement( url = "https://hapi.fhir.org/baseR4", username = NULL, password = NULL, token = NULL, add_headers = NULL, brackets = NULL, sep = " ::: ", log_errors = NULL, verbose = deprecated() )
url |
The base URL of the FHIR server. |
username |
A character vector of length one containing the username for basic authentication. Defaults to NULL, meaning no authentication. |
password |
A character vector of length one containing the password for basic authentication. Defaults to NULL, meaning no authentication. |
token |
A character vector of length one or object of class httr::Token, for bearer token authentication (e.g. OAuth2). See |
add_headers |
A named character vector of custom headers to add to the HTTP request, e.g. |
brackets |
A character vector of length two defining the brackets surrounding indices for multiple entries, e.g. |
sep |
A character vector of length one to separate pasted multiple entries |
log_errors |
Either |
verbose |
A list of data frames containing the information from the statement
## Not run: #without indices cap <- fhir_capability_statement(url = "https://server.fire.ly") #with indices cap <- fhir_capability_statement(url = "https://server.fire.ly", brackets = c("[","]"), sep = " || ") #melt searchInclude variable resources <- fhir_melt(cap$Resources, columns = "searchInclude", brackets = c("[", "]"), sep = " || ", all_columns = FALSE) #remove indices resources <- fhir_rm_indices(resources, brackets = c("[", "]")) head(resources) ## End(Not run)
## Not run: #without indices cap <- fhir_capability_statement(url = "https://server.fire.ly") #with indices cap <- fhir_capability_statement(url = "https://server.fire.ly", brackets = c("[","]"), sep = " || ") #melt searchInclude variable resources <- fhir_melt(cap$Resources, columns = "searchInclude", brackets = c("[", "]"), sep = " || ", all_columns = FALSE) #remove indices resources <- fhir_rm_indices(resources, brackets = c("[", "]")) head(resources) ## End(Not run)
fhir_crack()
into separate columns.This function turns a table from compact format into wide format. Every column containing multiple entries will be turned into multiple columns. The number of columns created from a single column in the original table is determined by the maximum number of multiple entries occurring in this column. Rows with less than the maximally occurring number of entries will be filled with NA values.
fhir_cast(indexed_df, brackets, sep, verbose = 1)
fhir_cast(indexed_df, brackets, sep, verbose = 1)
indexed_df |
A compact data.frame/data.table with indexed multiple entries. Column names should reflect the XPath expression of the respective element. |
brackets |
A character vector of length two, defining the brackets used for the indices. |
sep |
A character vector of length one defining the separator that was used when pasting together multiple entries in |
verbose |
An integer vector of length one. If 0, nothing is printed, if 1, only general progress is printed, if > 1, progress for each variable is printed. Defaults to 1. |
For fhir_cast()
to work properly, column names of the input data must reflect the Xpath to the corresponding resource element
with .
as a separator, e.g. code.coding.system
. These names are produced automatically by fhir_crack()
when the names are not explicitly set in the cols
element of the fhir_table_description()
/fhir_design()
.
In the names of the newly created columns the indices will be added in front of the column names, similar to the result of fhir_crack()
with
format="wide"
. See examples and the corresponding package vignette for a more detailed description.
fhir_crack()
, fhir_melt()
, fhir_build_bundle()
#unserialize example bundles <- fhir_unserialize(bundles = example_bundles1) #crack fhir resources table_desc <- fhir_table_description( resource = "Patient", brackets = c('[', ']'), sep = " ", keep_attr=TRUE ) df <- fhir_crack(bundles = bundles, design = table_desc) #original df df #cast fhir_cast(df, brackets=c('[', ']'), sep = ' ', verbose = 0)
#unserialize example bundles <- fhir_unserialize(bundles = example_bundles1) #crack fhir resources table_desc <- fhir_table_description( resource = "Patient", brackets = c('[', ']'), sep = " ", keep_attr=TRUE ) df <- fhir_crack(bundles = bundles, design = table_desc) #original df df #cast fhir_cast(df, brackets=c('[', ']'), sep = ' ', verbose = 0)
This function collapses multiple entries that belong to the same higher level FHIR element (see examples).
fhir_collapse(indexed_data_frame, columns, sep, brackets, collapse = " ")
fhir_collapse(indexed_data_frame, columns, sep, brackets, collapse = " ")
indexed_data_frame |
A data.frame/data.table with indexed multiple entries. |
columns |
A character vector of column names where values should be collapsed |
sep |
A character vector of length one defining the separator that was used when pasting together multiple entries in |
brackets |
A character vector of length two, defining the brackets used for the indices. |
collapse |
A character vector of length one used to separate the collapsed fields. Defaults to blank space. |
Currently this function is only needed for very few FHIR elements where multiple values should be kept together
in the melting process. To our knowledge, this is only true for address.line elements and name.given elements.
Rather than building the cross product with all other elements in the resource as done by fhir_melt()
, these
elements should be collapsed into a single entry before melting. See examples to get a better idea of this.
The modified data.table/data.frame with collapsed multiple entries
### First example: Keep name.given elements together #unserialize example bundles <- fhir_unserialize(bundles = example_bundles7) #Have a look at the structure of example_bundles7 ?example_bundles7 #Define sep and brackets sep <- "|" brackets <- c("[", "]") #crack fhir resources table_desc <- fhir_table_description( resource = "Patient", brackets = brackets, sep = sep ) df <- fhir_crack(bundles = bundles, design = table_desc) df #name.given elements from the same name (i.e. the official vs. the nickname) #should be collapsed df2 <- fhir_collapse(df, columns = "name.given", sep = sep, brackets = brackets) df2 #Next the name can be molten fhir_melt(df2, brackets = brackets, sep = sep, columns = fhir_common_columns(df2,"name")) ### Second: Keep address line elements together #unserialize example bundles <- fhir_unserialize(bundles = example_bundles6) #Have a look at the structure of example_bundles6 ?example_bundles6 #Define sep and brackets sep <- "|" brackets <- c("[", "]") #crack fhir resources table_desc <- fhir_table_description( resource = "Patient", brackets = brackets, sep = sep ) df <- fhir_crack(bundles = bundles, design = table_desc) df #Address.line elements from the same address (i.e. the work vs. the home address) #should be collapsed df2 <- fhir_collapse(df, columns = "address.line", sep = sep, brackets = brackets, collapse = ", ") df2 #Next the address can be molten fhir_melt(df2, brackets = brackets, sep = sep, columns = fhir_common_columns(df2,"address"))
### First example: Keep name.given elements together #unserialize example bundles <- fhir_unserialize(bundles = example_bundles7) #Have a look at the structure of example_bundles7 ?example_bundles7 #Define sep and brackets sep <- "|" brackets <- c("[", "]") #crack fhir resources table_desc <- fhir_table_description( resource = "Patient", brackets = brackets, sep = sep ) df <- fhir_crack(bundles = bundles, design = table_desc) df #name.given elements from the same name (i.e. the official vs. the nickname) #should be collapsed df2 <- fhir_collapse(df, columns = "name.given", sep = sep, brackets = brackets) df2 #Next the name can be molten fhir_melt(df2, brackets = brackets, sep = sep, columns = fhir_common_columns(df2,"name")) ### Second: Keep address line elements together #unserialize example bundles <- fhir_unserialize(bundles = example_bundles6) #Have a look at the structure of example_bundles6 ?example_bundles6 #Define sep and brackets sep <- "|" brackets <- c("[", "]") #crack fhir resources table_desc <- fhir_table_description( resource = "Patient", brackets = brackets, sep = sep ) df <- fhir_crack(bundles = bundles, design = table_desc) df #Address.line elements from the same address (i.e. the work vs. the home address) #should be collapsed df2 <- fhir_collapse(df, columns = "address.line", sep = sep, brackets = brackets, collapse = ", ") df2 #Next the address can be molten fhir_melt(df2, brackets = brackets, sep = sep, columns = fhir_common_columns(df2,"address"))
An object of class fhir_columns
is part of a fhir_table_description
in a fhir_design
and holds information on the elements
that should be extracted from the FHIR resources, as well as the column names of the resulting data.frame.
The elements to be extracted are indicated by XPath xpaths. If no column names are provided,
they are generated automatically and reflect the elements position in the resource.
fhir_columns(xpaths, colnames) ## S4 method for signature 'missing,missing' fhir_columns() ## S4 method for signature 'NULL,missing' fhir_columns(xpaths) ## S4 method for signature 'character,character' fhir_columns(xpaths, colnames) ## S4 method for signature 'character,missing' fhir_columns(xpaths) ## S4 method for signature 'list,missing' fhir_columns(xpaths)
fhir_columns(xpaths, colnames) ## S4 method for signature 'missing,missing' fhir_columns() ## S4 method for signature 'NULL,missing' fhir_columns(xpaths) ## S4 method for signature 'character,character' fhir_columns(xpaths, colnames) ## S4 method for signature 'character,missing' fhir_columns(xpaths) ## S4 method for signature 'list,missing' fhir_columns(xpaths)
xpaths |
A (named) character vector or (named) list containing xpath xpaths, or a fhir_xpath_expression object. |
colnames |
The names of the columns to create. If no colnames are provided and the list or vector
in |
#provide colnames explicitly fhir_columns(xpaths = c("name/given", "code/coding/code"), colnames = c("name", "code")) #colnames are taken from xpaths argument fhir_columns(xpaths = c(name = "name/given", code = "code/coding/code")) #colnames are taken from xpaths argument fhir_columns(xpaths = list(name = "name/given", code = "code/coding/code")) #colnames are generated automatically fhir_columns(xpaths = c("name/given", "code/coding/code"))
#provide colnames explicitly fhir_columns(xpaths = c("name/given", "code/coding/code"), colnames = c("name", "code")) #colnames are taken from xpaths argument fhir_columns(xpaths = c(name = "name/given", code = "code/coding/code")) #colnames are taken from xpaths argument fhir_columns(xpaths = list(name = "name/given", code = "code/coding/code")) #colnames are generated automatically fhir_columns(xpaths = c("name/given", "code/coding/code"))
An object of class fhir_columns
is part of a fhir_table_description
in a fhir_design and holds information on the elements
that should be extracted from the FHIR resources, as well as the column names of the resulting data.frame.
The elements to be extracted are indicated by XPath xpaths.
names
The column names
This is a convenience function to find all column names in a data frame starting with the same string that can
then be used for fhir_melt()
.
fhir_common_columns(data_frame, column_names_prefix)
fhir_common_columns(data_frame, column_names_prefix)
data_frame |
A data.frame/data.table with automatically named columns as produced by |
column_names_prefix |
A string containing the common prefix of the desired columns. |
It is intended for use on data frames with column names that have been automatically produced by fhir_design()
/fhir_crack()
and follow the form level1.level2.level3
such as name.given
or code.coding.system
.
Note that this function will only work on column names following exactly this scheme.
The resulting character vector can be used for melting all columns belonging to the same attribute in an indexed data frame,
see ?fhir_melt
.
A character vector with the names of all columns matching column_names_prefix
.
fhir_melt()
, fhir_rm_indices()
#unserialize example bundles bundles <- fhir_unserialize(bundles = medication_bundles) #crack Patient Resources pats <- fhir_table_description(resource = "Patient") df <- fhir_crack(bundles = bundles, design = pats) #look at automatically generated names names(df) #extract all column names beginning with the string "name" fhir_common_columns(data_frame = df, column_names_prefix = "name")
#unserialize example bundles bundles <- fhir_unserialize(bundles = medication_bundles) #crack Patient Resources pats <- fhir_table_description(resource = "Patient") df <- fhir_crack(bundles = bundles, design = pats) #look at automatically generated names names(df) #extract all column names beginning with the string "name" fhir_common_columns(data_frame = df, column_names_prefix = "name")
Downloads a count of resources matching the resource type and search parameters specified in resource
and parameters
.
This function makes use of the _summary=count
parameter of FHIR search and is therefore able to count resources on the server
without actually downloading them.
fhir_count_resource( base_url, resource, parameters = NULL, username = NULL, password = NULL, token = NULL, add_headers = NULL )
fhir_count_resource( base_url, resource, parameters = NULL, username = NULL, password = NULL, token = NULL, add_headers = NULL )
base_url |
A character vector of length one specifying the base URL of the FHIR server, e.g. |
resource |
A character vector of length one or fhir_resource_type object with the resource type to be searched, e.g. |
parameters |
Optional. Either a length 1 character vector containing properly formatted FHIR search parameters, e.g.
|
username |
A character vector of length one containing the username for basic authentication. |
password |
A character vector of length one containing the password for basic authentication. |
token |
A character vector of length one or object of class httr::Token, for bearer token authentication (e.g. OAuth2). See |
add_headers |
A named character vector of custom headers to add to the HTTP request, e.g. |
For more information on authentication options, please see the help page of fhir_search()
An integer of length 1 containing the number of resources matching the type and search parameters specified in resource
and parameters
.
#the try({}, silent = TRUE) statement is only there to catch errors when the server is down #you can skip it when the server is reachable try({ #number of female Patient resources on the server fhir_count_resource( base_url = 'https://vonk.fire.ly/R4', resource = "Patient", parameters = c(gender = "female")) }, silent = TRUE)
#the try({}, silent = TRUE) statement is only there to catch errors when the server is down #you can skip it when the server is reachable try({ #number of female Patient resources on the server fhir_count_resource( base_url = 'https://vonk.fire.ly/R4', resource = "Patient", parameters = c(gender = "female")) }, silent = TRUE)
Converts a fhir_bundle_list (the result of fhir_search()
) to a data.frame/data.table or list of df/dt,
if more than one resource type is extracted at once.
There are two main output formats for the table: compact and wide. They differ regarding their handling of multiple occurrences of
the same FHIR element (e.g. Patient.adress
). In the compact format multiple occurrences are pasted together into one cell/column,
in the wide format multiple occurrences are distributed over several (indexed) columns. If none of the resources contains any multiple
values on the extracted elements, the two formats will result in the same structure.
To increase speed with larger amounts of data the cracking process can be parallelised over a number of cores defined in the
ncores
argument.
fhir_crack( bundles, design, sep = NULL, brackets = NULL, rm_empty_cols = NULL, verbose = 2, data.table = FALSE, format = NULL, keep_attr = NULL, ncores = 1 ) ## S4 method for signature 'ANY,fhir_table_description' fhir_crack( bundles, design, sep = NULL, brackets = NULL, rm_empty_cols = NULL, verbose = 2, data.table = FALSE, format = NULL, keep_attr = NULL, ncores = 1 ) ## S4 method for signature 'ANY,fhir_design' fhir_crack( bundles, design, sep = NULL, brackets = NULL, rm_empty_cols = NULL, verbose = 2, data.table = FALSE, format = NULL, keep_attr = NULL, ncores = 1 )
fhir_crack( bundles, design, sep = NULL, brackets = NULL, rm_empty_cols = NULL, verbose = 2, data.table = FALSE, format = NULL, keep_attr = NULL, ncores = 1 ) ## S4 method for signature 'ANY,fhir_table_description' fhir_crack( bundles, design, sep = NULL, brackets = NULL, rm_empty_cols = NULL, verbose = 2, data.table = FALSE, format = NULL, keep_attr = NULL, ncores = 1 ) ## S4 method for signature 'ANY,fhir_design' fhir_crack( bundles, design, sep = NULL, brackets = NULL, rm_empty_cols = NULL, verbose = 2, data.table = FALSE, format = NULL, keep_attr = NULL, ncores = 1 )
bundles |
A FHIR search result as returned by |
design |
A fhir_design or fhir_table_description object. See |
sep |
Optional. A character of length one containing the separator string used for separating multiple entries in cells when |
brackets |
Optional. A character of length one or two used for the indices of multiple entries, which will overwrite the |
rm_empty_cols |
Optional. Remove empty columns? Logical scalar which will overwrite the |
verbose |
An integer vector of length one. If 0, nothing is printed, if 1, only finishing message is printed, if > 1, extraction progress will be printed. Defaults to 2. |
data.table |
A logical vector of length one. If it is set to |
format |
Optional. A character of length one indicating whether the resulting table should be cracked to a |
keep_attr |
Optional. A logical of length one indicating whether the attribute name of the respective element ( |
ncores |
Either |
If a fhir_design was used, the result is a list of data.frames, i.e. a fhir_df_list object, or a list of data.tables, i.e. a fhir_dt_list object. If a fhir_table_description was used, the result is a single data.frame/data.table.
Downloading bundles from a FHIR server: fhir_search()
Creating designs/table_descriptions: fhir_table_description()
and fhir_design()
Dealing with multiple entries: fhir_melt()
, fhir_cast()
, fhir_rm_indices()
#unserialize example bundle bundles <- fhir_unserialize(medication_bundles) ###Example 1### #Extract just one resource type #define attributes to extract med_desc <- fhir_table_description( resource = "MedicationStatement", cols = c( id = "id", status = "status", system = "medicationCodeableConcept/coding/system", code = "medicationCodeableConcept/coding/code", display = "medicationCodeableConcept/coding/display" ) ) med_df <- fhir_crack(bundles = bundles, design = med_desc) head(med_df) #data.frame ###Example 2### #extract two resource types at once pat_desc <- fhir_table_description( resource = "Patient" ) design <- fhir_design(med_desc, pat_desc) df_list <- fhir_crack(bundles = bundles, design = design) #list of data.frames/fhir_df_list head(df_list$med_desc) head(df_list$pat_desc) #The design that was used can be extracted from a fhir_df_list fhir_design(df_list) ###Example 3### #Filter values before extracting #unserialize example bundle b <- fhir_unserialize(bundles = example_bundles5) #only extract codings with loinc system table_desc <- fhir_table_description( resource = "Observation", cols = c( id = "id", loinc = "code/coding[system[@value='http://loinc.org']]/code", display = "code/coding[system[@value='http://loinc.org']]/display" ) ) table <- fhir_crack(bundles = b, design = table_desc) table
#unserialize example bundle bundles <- fhir_unserialize(medication_bundles) ###Example 1### #Extract just one resource type #define attributes to extract med_desc <- fhir_table_description( resource = "MedicationStatement", cols = c( id = "id", status = "status", system = "medicationCodeableConcept/coding/system", code = "medicationCodeableConcept/coding/code", display = "medicationCodeableConcept/coding/display" ) ) med_df <- fhir_crack(bundles = bundles, design = med_desc) head(med_df) #data.frame ###Example 2### #extract two resource types at once pat_desc <- fhir_table_description( resource = "Patient" ) design <- fhir_design(med_desc, pat_desc) df_list <- fhir_crack(bundles = bundles, design = design) #list of data.frames/fhir_df_list head(df_list$med_desc) head(df_list$pat_desc) #The design that was used can be extracted from a fhir_df_list fhir_design(df_list) ###Example 3### #Filter values before extracting #unserialize example bundle b <- fhir_unserialize(bundles = example_bundles5) #only extract codings with loinc system table_desc <- fhir_table_description( resource = "Observation", cols = c( id = "id", loinc = "code/coding[system[@value='http://loinc.org']]/code", display = "code/coding[system[@value='http://loinc.org']]/display" ) ) table <- fhir_crack(bundles = b, design = table_desc) table
fhir_search()
or fhir_url()
Return FHIR search request used in last call to fhir_search()
or fhir_url()
fhir_current_request()
fhir_current_request()
An object of class fhir_url()
#the try({}, silent = TRUE) statement is only there to catch errors when the server is down #you can skip it when the server is reachable try({ request <- fhir_url(url = "https://server.fire.ly", resource = "Patient") fhir_current_request() fhir_search("https://server.fire.ly/Medication", max_bundles = 1) fhir_current_request() },silent = TRUE)
#the try({}, silent = TRUE) statement is only there to catch errors when the server is down #you can skip it when the server is reachable try({ request <- fhir_url(url = "https://server.fire.ly", resource = "Patient") fhir_current_request() fhir_search("https://server.fire.ly/Medication", max_bundles = 1) fhir_current_request() },silent = TRUE)
A fhir_design
is a named list of fhir_table_description
objects (See fhir_table_description()
)
and should be created using the function described here. The design is used in fhir_crack()
to tell
the function how to flatten each resource type.
fhir_design(...) ## S4 method for signature 'fhir_table_description' fhir_design(...) ## S4 method for signature 'list' fhir_design(...) ## S4 method for signature 'fhir_table_list' fhir_design(...)
fhir_design(...) ## S4 method for signature 'fhir_table_description' fhir_design(...) ## S4 method for signature 'list' fhir_design(...) ## S4 method for signature 'fhir_table_list' fhir_design(...)
... |
One or more |
A fhir_design
looks for example like this:
A fhir_design with 2 table_descriptions: A fhir_table_description with the following elements: fhir_resource_type: Patient fhir_columns: ------------ ----------------- column name | xpath expression ------------ ----------------- id | id name | name/family gender | gender ------------ ----------------- sep: '||' brackets: '[', ']' rm_empty_cols: FALSE format: 'compact' keep_attr: TRUE A fhir_table_description with the following elements: fhir_resource_type: MedicationAdministration fhir_columns: An empty fhir_columns object sep: ':::' brackets: no brackets rm_empty_cols: FALSE format: 'wide' keep_attr: TRUE
The names of the table_descriptions are taken from the names of the arguments. If the table_descriptions are
created within the call to fhir_design
and therefore have no names, the names will be created from the respective
resource type. See examples.
For backwards compatibility it is for the moment also possible to build it from an
old-style design as used in fhircrackr (< 1.0.0)
. See examples.
If this function is given an object of class fhir_df_list or fhir_dt_list, it will extract the design that was used to create the respective list.
fhir_table_description()
, fhir_crack()
####Example 1#### ###create fhir_table_descriptions first #see ?fhir_table_description for explanation pat <- fhir_table_description( resource = "Patient", cols = c( id = "id", name = "name/family", gender = "gender" ), sep = "||", brackets = c("[", "]"), rm_empty_cols = FALSE ) meds <- fhir_table_description(resource = "MedicationAdministration") ###create design #First option: Explicitly define names design1 <- fhir_design(Pats = pat, Medics = meds) print(design1) #Second option: Names are taken from the object names design2 <- fhir_design(pat, meds) print(design2) #Third option: Create table_description within fhir_design design3 <- fhir_design(fhir_table_description(resource = "MedicationAdministration")) print(design3) #Fourth option: Names are taken from named list design3 <- fhir_design(list(Patients = pat, Medications = meds)) print(design3) ###Example 2### ###Extract design from fhir_df_list/fhir_dt_list #unserialize and crack example bundles med_bundles <- fhir_unserialize(bundles = medication_bundles) dfs <- fhir_crack(bundles = med_bundles, design = design1) #extract design fhir_design(dfs)
####Example 1#### ###create fhir_table_descriptions first #see ?fhir_table_description for explanation pat <- fhir_table_description( resource = "Patient", cols = c( id = "id", name = "name/family", gender = "gender" ), sep = "||", brackets = c("[", "]"), rm_empty_cols = FALSE ) meds <- fhir_table_description(resource = "MedicationAdministration") ###create design #First option: Explicitly define names design1 <- fhir_design(Pats = pat, Medics = meds) print(design1) #Second option: Names are taken from the object names design2 <- fhir_design(pat, meds) print(design2) #Third option: Create table_description within fhir_design design3 <- fhir_design(fhir_table_description(resource = "MedicationAdministration")) print(design3) #Fourth option: Names are taken from named list design3 <- fhir_design(list(Patients = pat, Medications = meds)) print(design3) ###Example 2### ###Extract design from fhir_df_list/fhir_dt_list #unserialize and crack example bundles med_bundles <- fhir_unserialize(bundles = medication_bundles) dfs <- fhir_crack(bundles = med_bundles, design = design1) #extract design fhir_design(dfs)
fhir_crack()
A fhir_design is a named list of fhir_table_description objects. Each table_description
contains information on how to flatten one resource type which will result in one
data.frame. The fhir_design is passed to the function fhir_crack()
along with a
list of bundles containing FHIR resources.
.Data
The list of fhir_table_description
objects.
names
The names of the table_descriptions. Those will also be the names of the resulting data.frames.
fhir_table_description()
, fhir_crack()
fhir_crack()
Objects of this class are returned by fhir_crack()
when data.table=FALSE
(the default).
They behave like an ordinary named list of data.frames but have some additional information
in the slot design
.
names
Character vector containing the names of the data.frames.
design
An object of class fhir_design that was used to create the df_list.
fhir_crack()
Objects of this class are returned by fhir_crack()
when data.table=TRUE
.
They behave like an ordinary named list of data.tables but have some additional information
in the slot design
.
names
A character vector containing the names of the data.tables.
design
An object of class fhir_design that was used to create the dt_list.
Download the resource (aka logical) IDs of all resources matching the FHIR search request build from the resource type and search
parameters specified in resource
and parameters
. This function does not download the entire resources, but only extracts their IDs
using the _elements
parameter of FHIR Search.
fhir_get_resource_ids( base_url, resource, parameters = NULL, username = NULL, password = NULL, token = NULL, add_headers = NULL, verbose = 0 )
fhir_get_resource_ids( base_url, resource, parameters = NULL, username = NULL, password = NULL, token = NULL, add_headers = NULL, verbose = 0 )
base_url |
A character vector of length one specifying the base URL of the FHIR server, e.g. |
resource |
A character vector of length one or fhir_resource_type object with the resource type to be searched, e.g. |
parameters |
Optional. Either a length 1 character vector containing properly formatted FHIR search parameters, e.g.
|
username |
A character vector of length one containing the username for basic authentication. |
password |
A character vector of length one containing the password for basic authentication. |
token |
A character vector of length one or object of class httr::Token, for bearer token authentication (e.g. OAuth2). See |
add_headers |
A named character vector of custom headers to add to the HTTP request, e.g. |
verbose |
An integer of length 1 containing the level of verbosity. Defaults to 0. |
For more information on authentication options, please see the help page of fhir_search()
A character vector containing the resource (aka logical) IDs of all requested resources.
fhir_search()
, fhir_get_resources_by_ids()
#the try({}, silent = TRUE) statement is only there to catch errors when the server is down #you can skip it when the server is reachable try({ fhir_get_resource_ids( base_url = 'https://vonk.fire.ly/R4', resource = "Patient", parameters = "gender=female", verbose=1) }, silent = TRUE)
#the try({}, silent = TRUE) statement is only there to catch errors when the server is down #you can skip it when the server is reachable try({ fhir_get_resource_ids( base_url = 'https://vonk.fire.ly/R4', resource = "Patient", parameters = "gender=female", verbose=1) }, silent = TRUE)
Downloads FHIR resources represented by a vector of resource IDs.
fhir_get_resources_by_ids( base_url, resource, ids, id_param = "_id", parameters = NULL, username = NULL, password = NULL, token = NULL, add_headers = NULL, verbose = 0 )
fhir_get_resources_by_ids( base_url, resource, ids, id_param = "_id", parameters = NULL, username = NULL, password = NULL, token = NULL, add_headers = NULL, verbose = 0 )
base_url |
A character vector of length one specifying the base URL of the FHIR server, e.g. |
resource |
A character vector of length one or fhir_resource_type object with the resource type to be searched, e.g. |
ids |
A character vector containing the IDs of the resources that should be downloaded. In the default setting these should be resource (aka logical) IDs. |
id_param |
A character vector of length one containing the FHIR Search parameter belonging to the ids in |
parameters |
FHIR Search parameters to further restrict the set of resources that is returned, e.g. |
username |
A character vector of length one containing the username for basic authentication. |
password |
A character vector of length one containing the password for basic authentication. |
token |
A character vector of length one or object of class httr::Token, for bearer token authentication (e.g. OAuth2). See |
add_headers |
A named character vector of custom headers to add to the HTTP request, e.g. |
verbose |
An integer vector of length 1 containing the level of verbosity. Defaults to 0. |
This function takes a character vector ids
containing logical Ids of resources of a given type (specified in resource
) on a
FHIR server (specified in base_url
) and downloads the corresponding resources from the server. The function will attempt to download the resources using a
FHIR search request via POST where the IDs are part of the body. See fhir_search()
for details. If this fails
(e.g. because the server doesn't allow POST operations), the function falls back on a GET request. If the set of ids is too long to fit
into one GET request (i.e. if the request gets longer than 2083 characters), it will be spread across several requests.
For more information on authentication options, please see the help page of fhir_search()
A fhir_bundle_list containing the downloaded resources.
fhir_search()
, fhir_get_resource_ids()
#the try({}, silent = TRUE) statement is only there to catch errors when the server is down #you can skip it when the server is reachable try({ #find IDs of Patient resources representing Homer Simpson ids <- fhir_get_resource_ids( base_url = 'https://hapi.fhir.org/baseR4', resource = "Patient", parameters = "name=Homer&name=Simpson") #Download all corresponding resources bundles <- fhir_get_resources_by_ids( base_url = 'https://hapi.fhir.org/baseR4', resource = "Patient", ids = ids) #have a look at the resources fhir_crack( bundles, fhir_table_description( resource = "Patient", cols = list( ID = "id", given = "name/given", family = "name/family"))) }, silent = TRUE)
#the try({}, silent = TRUE) statement is only there to catch errors when the server is down #you can skip it when the server is reachable try({ #find IDs of Patient resources representing Homer Simpson ids <- fhir_get_resource_ids( base_url = 'https://hapi.fhir.org/baseR4', resource = "Patient", parameters = "name=Homer&name=Simpson") #Download all corresponding resources bundles <- fhir_get_resources_by_ids( base_url = 'https://hapi.fhir.org/baseR4', resource = "Patient", ids = ids) #have a look at the resources fhir_crack( bundles, fhir_table_description( resource = "Patient", cols = list( ID = "id", given = "name/given", family = "name/family"))) }, silent = TRUE)
Checks if a fhir_bundle_xml or fhir_bundle_list is empty, i.e. does not contain any resources.
fhir_is_empty(bundles) ## S4 method for signature 'fhir_bundle_list' fhir_is_empty(bundles) ## S4 method for signature 'fhir_bundle_xml' fhir_is_empty(bundles)
fhir_is_empty(bundles) ## S4 method for signature 'fhir_bundle_list' fhir_is_empty(bundles) ## S4 method for signature 'fhir_bundle_xml' fhir_is_empty(bundles)
bundles |
A FHIR search result as returned by |
Empty bundles are returned when a search on a FHIR server does not yield any resources, such as when no resources on the server match the specified search criteria. In this case, the server responds with an empty searchset bundle. This function checks whether:
For objects of type fhir_bundle_xml, the bundle contains at least one "entry" element
(if not, the bundle is empty and the functions returns TRUE
)
For objects of type fhir_bundle_list, the first bundle in the list contains at least one "entry" element
(if not, the bundle is empty and the functions returns TRUE
)
TRUE
if the bundle/bundle list is empty, FALSE
if it is not empty.
#Load empty example bundles bundles <- fhir_unserialize(example_bundles_empty) bundles fhir_is_empty(bundles) #Load non-empty example bundles bundles <- fhir_unserialize(patient_bundles) bundles fhir_is_empty(bundles)
#Load empty example bundles bundles <- fhir_unserialize(example_bundles_empty) bundles fhir_is_empty(bundles) #Load non-empty example bundles bundles <- fhir_unserialize(patient_bundles) bundles fhir_is_empty(bundles)
Reads all bundles stored as xml files from a directory.
fhir_load(directory, indices = NULL, pattern = "^[0-9]+\\.xml$")
fhir_load(directory, indices = NULL, pattern = "^[0-9]+\\.xml$")
directory |
A character vector of length one containing the path to the folder were the files are stored. |
indices |
A numeric vector of integers indicating which bundles from the specified directory should be loaded. Defaults to NULL meaning all bundles from the directory are loaded. |
pattern |
A character vector of length one with a regex expression defining the naming pattern of the xml files
to be read. Defaults to the regex expression matching file names as produced by |
#unserialize example bundle bundles <- fhir_unserialize(medication_bundles) length(bundles) #save to temporary directory dir <- tempdir() fhir_save(bundles, directory = dir) #load from temporary directory loaded_bundles <- fhir_load(dir) length(loaded_bundles) #load only two, the second and the third bundle loaded_bundles <- fhir_load(dir, indices = c(2,3)) length(loaded_bundles)
#unserialize example bundle bundles <- fhir_unserialize(medication_bundles) length(bundles) #save to temporary directory dir <- tempdir() fhir_save(bundles, directory = dir) #load from temporary directory loaded_bundles <- fhir_load(dir) length(loaded_bundles) #load only two, the second and the third bundle loaded_bundles <- fhir_load(dir, indices = c(2,3)) length(loaded_bundles)
Loads a fhir_design for use with fhir_crack()
from an xml file into R.
fhir_load_design(file)
fhir_load_design(file)
file |
A string specifying the file from which to read. |
A fhir_design object. See ?fhir_design
.
fhir_design()
, fhir_table_description()
, fhir_save_design()
table_desc1 <- fhir_table_description( resource = 'Patient', cols = c( id = 'id', name = 'name/family', gender = 'gender' ), sep = ':::', brackets = c('[', ']'), rm_empty_cols = FALSE, format = 'compact', keep_attr = FALSE ) table_desc2 <- fhir_table_description( resource = 'Observation', cols = c( 'code/coding/system', 'code/coding/code' ) ) design <- fhir_design( Patients = table_desc1, Observations = table_desc2 ) temp <- tempfile() fhir_save_design(design = design, file = temp) design <- fhir_load_design(file = temp)
table_desc1 <- fhir_table_description( resource = 'Patient', cols = c( id = 'id', name = 'name/family', gender = 'gender' ), sep = ':::', brackets = c('[', ']'), rm_empty_cols = FALSE, format = 'compact', keep_attr = FALSE ) table_desc2 <- fhir_table_description( resource = 'Observation', cols = c( 'code/coding/system', 'code/coding/code' ) ) design <- fhir_design( Patients = table_desc1, Observations = table_desc2 ) temp <- tempfile() fhir_save_design(design = design, file = temp) design <- fhir_load_design(file = temp)
This function divides multiple entries in an indexed data frame as produced by fhir_crack()
into separate rows.
fhir_melt( indexed_data_frame, columns, brackets = c("<", ">"), sep = " ", id_name = "resource_identifier", all_columns = FALSE )
fhir_melt( indexed_data_frame, columns, brackets = c("<", ">"), sep = " ", id_name = "resource_identifier", all_columns = FALSE )
indexed_data_frame |
A data.frame/data.table with indexed multiple entries. |
columns |
A character vector specifying the names of all columns that should be molten simultaneously. It is advisable to only melt columns simultaneously that belong to the same (repeating) attribute! |
brackets |
A character vector of length two, defining the brackets used for the indices. |
sep |
A character vector of length one defining the separator that was used when pasting together multiple entries in |
id_name |
A character vector of length one, the name of the column that will hold the identification of the origin of the new rows. |
all_columns |
Return all columns? Defaults to |
Every row containing values that consist of multiple entries on the variables specified by the argument columns
will be turned into multiple rows, one for each entry. Values on other variables will be repeated in all the new rows.
The new data.frame will contain only the molten variables (if all_cloumns = FALSE
) or all variables
(if all_columns = TRUE
) as well as an additional variable resource_identifier
that maps which rows came
from the same origin. The name of this column can be changed in the argument id_name
.
For a more detailed description on how to use this function please see the corresponding package vignette.
A data.frame/data.table where each entry from the variables in columns
appears in a separate row.
fhir_common_columns()
, fhir_rm_indices()
#unserialize example bundles <- fhir_unserialize(bundles = example_bundles1) #crack fhir resources table_desc <- fhir_table_description( resource = "Patient", brackets = c("[", "]"), sep = " " ) df <- fhir_crack(bundles = bundles, design = table_desc) #find all column names associated with attribute address col_names <- fhir_common_columns(df, "address") #original data frame df #only keep address columns fhir_melt( indexed_data_frame = df, columns = col_names, brackets = c("[", "]"), sep = " " ) #keep all columns fhir_melt(indexed_data_frame = df, columns = col_names, brackets = c("[","]"), sep = " ", all_columns = TRUE)
#unserialize example bundles <- fhir_unserialize(bundles = example_bundles1) #crack fhir resources table_desc <- fhir_table_description( resource = "Patient", brackets = c("[", "]"), sep = " " ) df <- fhir_crack(bundles = bundles, design = table_desc) #find all column names associated with attribute address col_names <- fhir_common_columns(df, "address") #original data frame df #only keep address columns fhir_melt( indexed_data_frame = df, columns = col_names, brackets = c("[", "]"), sep = " " ) #keep all columns fhir_melt(indexed_data_frame = df, columns = col_names, brackets = c("[","]"), sep = " ", all_columns = TRUE)
This function divides all multiple entries in an indexed data frame as produced by fhir_crack()
into separate rows.
fhir_melt_all(indexed_data_frame, brackets, sep, column_name_separator = ".")
fhir_melt_all(indexed_data_frame, brackets, sep, column_name_separator = ".")
indexed_data_frame |
A data.frame/data.table with indexed multiple entries. |
brackets |
A character vector of length two, defining the brackets used for the indices. |
sep |
A character vector of length one defining the separator that was used when pasting together multiple entries in |
column_name_separator |
A character string that separates element levels column names. Defaults to ".", which is used when
column names were generated automatically with |
The function repeatedly calls fhir_melt()
on groups of columns that belong to the same
FHIR element (e.g. address.city
, address.country
and address.type
) until every cell contains a single value.
If there is more than one FHIR element with multiple values (e.g. multiple address elements and multiple name
elements), every possible combination of the two elements will appear in the resulting table.
Caution! This creates something like a cross product of all values and can multiply the number of rows from the original
table considerably.
A completely molten data.table.
#unserialize example bundles <- fhir_unserialize(bundles = example_bundles1) #crack fhir resources table_desc <- fhir_table_description( resource = "Patient", brackets = c("[", "]"), sep = " " ) df <- fhir_crack(bundles = bundles, design = table_desc) #original data frame df #melt all multiple entries fhir_melt_all( indexed_data_frame = df, brackets = c("[", "]"), sep = " " )
#unserialize example bundles <- fhir_unserialize(bundles = example_bundles1) #crack fhir resources table_desc <- fhir_table_description( resource = "Patient", brackets = c("[", "]"), sep = " " ) df <- fhir_crack(bundles = bundles, design = table_desc) #original data frame df #melt all multiple entries fhir_melt_all( indexed_data_frame = df, brackets = c("[", "]"), sep = " " )
fhir_next_bundle_url() gives the link to the next available bundle, either of the bundle
you provided in the argument bundle
or of the last call to fhir_search()
, if bundle=NULL
(the default).
This function is useful when you don't have a lot of memory available or when a download of bundles was
interrupted for some reason. In case of small memory, you can use fhir_next_bundle_url
together with the
max_bundle
argument from fhir_search()
to download bundles in smaller batches in a loop.
See details in the example.
fhir_next_bundle_url(bundle = NULL)
fhir_next_bundle_url(bundle = NULL)
bundle |
The bundle from which you wish to extract the next link. If this is |
A fhir_url object referencing next bundle available on the FHIR server. Empty fhir_url / character vector, if no further bundle is available.
#' #the try({}, silent = TRUE) statement is only there to catch errors when the server is down #you can skip it when the server is reachable try({ # workflow for small memory environments, downloading small batches of bundles # for really small memory environments consider also using the `_count` option in # your FHIR search request. # You can iteratively download, crack and save the bundles until all bundles are processed or the # desired number of bundles is reached. url <- fhir_url("https://server.fire.ly/Patient") count <- 0 obs <- fhir_table_description(resource = "Patient") design <- fhir_design(obs) while(length(url)>0 && count < 5){ bundles <- fhir_search(url, max_bundles = 2) tables <- fhir_crack(bundles, design) save(tables, file = paste0(tempdir(),"/table_", count, ".RData")) count <- count + 1 url <- fhir_next_bundle_url() } #you can see the saved tables here: dir(tempdir()) }, silent = TRUE)
#' #the try({}, silent = TRUE) statement is only there to catch errors when the server is down #you can skip it when the server is reachable try({ # workflow for small memory environments, downloading small batches of bundles # for really small memory environments consider also using the `_count` option in # your FHIR search request. # You can iteratively download, crack and save the bundles until all bundles are processed or the # desired number of bundles is reached. url <- fhir_url("https://server.fire.ly/Patient") count <- 0 obs <- fhir_table_description(resource = "Patient") design <- fhir_design(obs) while(length(url)>0 && count < 5){ bundles <- fhir_search(url, max_bundles = 2) tables <- fhir_crack(bundles, design) save(tables, file = paste0(tempdir(),"/table_", count, ".RData")) count <- count + 1 url <- fhir_next_bundle_url() } #you can see the saved tables here: dir(tempdir()) }, silent = TRUE)
This function is a convenience wrapper around httr::POST()
.
fhir_post( url, body, username = NULL, password = NULL, token = NULL, add_headers = NULL, verbose = 1, log_errors = NULL ) ## S4 method for signature 'ANY,fhir_resource' fhir_post( url, body, username = NULL, password = NULL, token = NULL, add_headers = NULL, verbose = 1, log_errors = NULL ) ## S4 method for signature 'ANY,fhir_bundle_xml' fhir_post( url, body, username = NULL, password = NULL, token = NULL, add_headers = NULL, verbose = 1, log_errors = NULL ) ## S4 method for signature 'ANY,fhir_body' fhir_post( url, body, username = NULL, password = NULL, token = NULL, add_headers = NULL, verbose = 1, log_errors = NULL )
fhir_post( url, body, username = NULL, password = NULL, token = NULL, add_headers = NULL, verbose = 1, log_errors = NULL ) ## S4 method for signature 'ANY,fhir_resource' fhir_post( url, body, username = NULL, password = NULL, token = NULL, add_headers = NULL, verbose = 1, log_errors = NULL ) ## S4 method for signature 'ANY,fhir_bundle_xml' fhir_post( url, body, username = NULL, password = NULL, token = NULL, add_headers = NULL, verbose = 1, log_errors = NULL ) ## S4 method for signature 'ANY,fhir_body' fhir_post( url, body, username = NULL, password = NULL, token = NULL, add_headers = NULL, verbose = 1, log_errors = NULL )
url |
An object of class fhir_url or a character vector of length one containing the url to POST to. |
body |
An object of class fhir_resource, fhir_bundle_xml or fhir_body. See details for how to generate them. |
username |
A character vector of length one containing the username for basic authentication. |
password |
A character vector of length one containing the password for basic authentication. |
token |
A character vector of length one or object of class httr::Token, for bearer token authentication (e.g. OAuth2). See |
add_headers |
A named character vector of custom headers to add to the HTTP request, e.g. |
verbose |
An integer vector of length one. If 0, nothing is printed, if > 0 success message is printed. Defaults to 1. |
log_errors |
Either |
fhir_post()
accepts four classes for the body:
A fhir_resource as created by fhir_build_resource()
. This is used when just a single resource should be POSTed to the server.
In this case url
must contain the base url plus the resource type, e.g. http://hapi.fhir.org/baseR4/Patient.
A fhir_bundle_xml representing a transaction or batch bundle as created by fhir_build_bundle()
.
A fhir_body as created by fhir_body()
. This is the most flexible approach, because within the fhir_body object you can represent
any kind of content
as a string and set the type
accordingly. See examples.
For examples of how to create the different body types see the respective help pages. For an example of the entire workflow around creating and POSTing resources, see the package vignette on recreating resources.
## Not run: ### 1. POST transaction bundle #unserialize example bundles bundle <- fhir_unserialize(transaction_bundle_example) #have a look at the bundle cat(toString(bundle)) #post fhir_post(url = "http://hapi.fhir.org/baseR4", body = bundle) ### 2. POST single resouce #unserialize example resource resource <- fhir_unserialize(example_resource1) #have a look at the resource resource #post url <- fhir_url(url = "http://hapi.fhir.org/baseR4", resource = "Patient") fhir_post(url = url, body = resource) ### 3. POST arbitrary body #define body body <- fhir_body(content = "<Patient> <gender value='female'/> </Patient>", type = "xml") #post url <- fhir_url(url = "http://hapi.fhir.org/baseR4", resource = "Patient") fhir_post(url = url, body = body) ## End(Not run)
## Not run: ### 1. POST transaction bundle #unserialize example bundles bundle <- fhir_unserialize(transaction_bundle_example) #have a look at the bundle cat(toString(bundle)) #post fhir_post(url = "http://hapi.fhir.org/baseR4", body = bundle) ### 2. POST single resouce #unserialize example resource resource <- fhir_unserialize(example_resource1) #have a look at the resource resource #post url <- fhir_url(url = "http://hapi.fhir.org/baseR4", resource = "Patient") fhir_post(url = url, body = resource) ### 3. POST arbitrary body #define body body <- fhir_body(content = "<Patient> <gender value='female'/> </Patient>", type = "xml") #post url <- fhir_url(url = "http://hapi.fhir.org/baseR4", resource = "Patient") fhir_post(url = url, body = body) ## End(Not run)
This function is a convenience wrapper around httr::PUT()
.
fhir_put( url, body, username = NULL, password = NULL, token = NULL, add_headers = NULL, verbose = 1, log_errors = NULL )
fhir_put( url, body, username = NULL, password = NULL, token = NULL, add_headers = NULL, verbose = 1, log_errors = NULL )
url |
An object of class fhir_url or a character vector of length one containing the url to PUT to. |
body |
An object of class fhir_resource or fhir_body. See details for how to generate them. |
username |
A character vector of length one containing the username for basic authentication. |
password |
A character vector of length one containing the password for basic authentication. |
token |
A character vector of length one or object of class httr::Token, for bearer token authentication (e.g. OAuth2). See |
add_headers |
A named character vector of custom headers to add to the HTTP request, e.g. |
verbose |
An integer vector of length one. If 0, nothing is printed, if > 0 success message is printed. Defaults to 1. |
log_errors |
Either |
fhir_put()
accepts two classes for the body:
A fhir_resource as created by fhir_build_resource()
. This is used when just a single resource should be PUT to the server.
In this case url
must contain the base url plus the resource type and the resource id,
e.g. http://hapi.fhir.org/baseR4/Patient/1a2b3c.
A fhir_body as created by fhir_body()
. This is the most flexible approach, because within the fhir_body object you can represent
any kind of content
as a string and set the type
accordingly. See examples.
For examples of how to create the different body types see the respective help pages. For an example of the entire workflow around creating and PUTing resources, see the package vignette on recreating resources.
## Not run: ### 1. PUT fhir__resource object #unserialize example resource resource <- fhir_unserialize(example_resource2) #have a look at the resource resource #put fhir_put(url = "http://hapi.fhir.org/baseR4/Patient/1a2b3c", body = resource) ### 2. PUT fhir_body object #define body body <- fhir_body(content = "<Patient> <id value='x1y2'/> <gender value='female'/> </Patient>", type = "xml") #put fhir_put(url = "http://hapi.fhir.org/baseR4/Patient/x1y2", body = body) ## End(Not run)
## Not run: ### 1. PUT fhir__resource object #unserialize example resource resource <- fhir_unserialize(example_resource2) #have a look at the resource resource #put fhir_put(url = "http://hapi.fhir.org/baseR4/Patient/1a2b3c", body = resource) ### 2. PUT fhir_body object #define body body <- fhir_body(content = "<Patient> <id value='x1y2'/> <gender value='female'/> </Patient>", type = "xml") #put fhir_put(url = "http://hapi.fhir.org/baseR4/Patient/x1y2", body = body) ## End(Not run)
fhir_search()
Whenever a call to fhir_search()
produces any http error, the error information is saved internally
until the next http error occurs (or the R session ends). The error information can be accessed with fhir_recent_http_error
.
If you want to log that information outside of your R session, set the argument log_errors
of fhir_search()
.
fhir_recent_http_error()
fhir_recent_http_error()
A string containing the error message
## Not run: fhir_search("https://server.fire.ly/Medicatio", max_bundles = 1) cat(fhir_recent_http_error()) ## End(Not run)
## Not run: fhir_search("https://server.fire.ly/Medicatio", max_bundles = 1) cat(fhir_recent_http_error()) ## End(Not run)
A Wrapper for fhir_url
fhir_request(url, resource = NULL, parameters = NULL, url_enc = TRUE)
fhir_request(url, resource = NULL, parameters = NULL, url_enc = TRUE)
url |
The same as for |
resource |
The same as for |
parameters |
The same as for |
url_enc |
The same as for |
The same as for fhir_url()
.
#provide full FHIR search request fhir_request(url = "http://hapi.fhir.org/baseR4/Patient?gender=male&_summary=count") #provide base url and resource type fhir_request( url = "http://hapi.fhir.org/baseR4", resource = "Patient" ) #parameters in one string fhir_request( url = "http://hapi.fhir.org/baseR4", resource = "Patient", parameters = "gender=male&_summary=count" ) #parameters as a named character fhir_request( url = "http://hapi.fhir.org/baseR4", resource = "Patient", parameters = c("gender" = "male", "_summary" = "count") ) #parameters as a named list fhir_request( url = "http://hapi.fhir.org/baseR4", resource = "Patient", parameters = list("gender" = "male", "_summary" = "count") )
#provide full FHIR search request fhir_request(url = "http://hapi.fhir.org/baseR4/Patient?gender=male&_summary=count") #provide base url and resource type fhir_request( url = "http://hapi.fhir.org/baseR4", resource = "Patient" ) #parameters in one string fhir_request( url = "http://hapi.fhir.org/baseR4", resource = "Patient", parameters = "gender=male&_summary=count" ) #parameters as a named character fhir_request( url = "http://hapi.fhir.org/baseR4", resource = "Patient", parameters = c("gender" = "male", "_summary" = "count") ) #parameters as a named list fhir_request( url = "http://hapi.fhir.org/baseR4", resource = "Patient", parameters = list("gender" = "male", "_summary" = "count") )
A fhir_resource_serialized
is a fhir_resource_xml
that has been serialized using fhir_serialize()
. In this form, the
resource cannot be used in any meaningful way, but it can be saved and loaded as an .RData
or .rds
object without breaking the
external pointers in the xml. See ?fhir_serialize
and ?fhir_unserialize
.
This function creates an object of class fhir_resource_type. It checks the resource type against the list
of resource types provided at https://hl7.org/FHIR/resourcelist.html, corrects wrong cases (which can be disabled with fix_capitalization = FALSE
)
and throws a warning if the resource cannot be found at hl7.org.
fhir_resource_type(string, fix_capitalization = TRUE)
fhir_resource_type(string, fix_capitalization = TRUE)
string |
A length one character vector containing the resource type. Will usually be one of the official FHIR resource types listed at https://hl7.org/FHIR/resourcelist.html |
fix_capitalization |
Correct wrong capitalization for known resource types? E.g. |
An fhir_resource_type object
fhir_resource_type(string = "Patient") fhir_resource_type(string = "medicationadministration")
fhir_resource_type(string = "Patient") fhir_resource_type(string = "medicationadministration")
An object of class fhir_resource_type
is a string containing a FHIR resource type.
It is part of a fhir_table_description
which in turn is part of a fhir_design
and used in
fhir_crack()
.
Create fhir_resource_xml object
fhir_resource_xml(resource) ## S4 method for signature 'xml_document' fhir_resource_xml(resource) ## S4 method for signature 'xml_node' fhir_resource_xml(resource) ## S4 method for signature 'character' fhir_resource_xml(resource)
fhir_resource_xml(resource) ## S4 method for signature 'xml_document' fhir_resource_xml(resource) ## S4 method for signature 'xml_node' fhir_resource_xml(resource) ## S4 method for signature 'character' fhir_resource_xml(resource)
resource |
A xml-object representing a FHIR resource |
fhir_resource_xml(resource = xml2::read_xml("<Patient><id value = '1'/></Patient>"))
fhir_resource_xml(resource = xml2::read_xml("<Patient><id value = '1'/></Patient>"))
A fhir_resource_xml
is an xml representation of a FHIR resource (https://www.hl7.org/fhir/resourcelist.html).
This function is a convenience wrapper for fhir_rm_tag()
that removes all <div> </div>
elements from an xml.
div
tags in FHIR resources contain html code, which is often server generated and in most cases neither relevant nor
usable for data analysis.
fhir_rm_div(x)
fhir_rm_div(x)
x |
A fhir_bundle_xml or fhir_bundle_list object or a character vector containing xml objects. |
An object of the same class as x
where all tags matching the tag
argument are removed.
#Example 1: Remove div tags from xmls in a character vector string <- c("Hallo<div>Please<p>Remove Me</p></div> World!", "A<div><div><p>B</p></div>C</div>D") fhir_rm_div(x = string) #Example 2: Remove div tags in a single fhir bundle bundle <- fhir_unserialize(patient_bundles)[[1]] #example bundle contains html parts in div tags: cat(toString(bundle)) #remove html parts bundle_cleaned <- fhir_rm_div(x = bundle) #have a look at the result cat(toString(bundle_cleaned)) #Example 3: Remove div tags in a list of fhir bundles bundle_list <- fhir_unserialize(patient_bundles) #remove html parts bundle_list_cleaned <- fhir_rm_div(x = bundle_list) #check out how much the size of the bundle list is reduced by removing html size_with_html <- sum(sapply(bundle_list, function(x)object.size(toString(x)))) size_without_html <- sum(sapply(bundle_list_cleaned, function(x)object.size(toString(x)))) size_without_html/size_with_html
#Example 1: Remove div tags from xmls in a character vector string <- c("Hallo<div>Please<p>Remove Me</p></div> World!", "A<div><div><p>B</p></div>C</div>D") fhir_rm_div(x = string) #Example 2: Remove div tags in a single fhir bundle bundle <- fhir_unserialize(patient_bundles)[[1]] #example bundle contains html parts in div tags: cat(toString(bundle)) #remove html parts bundle_cleaned <- fhir_rm_div(x = bundle) #have a look at the result cat(toString(bundle_cleaned)) #Example 3: Remove div tags in a list of fhir bundles bundle_list <- fhir_unserialize(patient_bundles) #remove html parts bundle_list_cleaned <- fhir_rm_div(x = bundle_list) #check out how much the size of the bundle list is reduced by removing html size_with_html <- sum(sapply(bundle_list, function(x)object.size(toString(x)))) size_without_html <- sum(sapply(bundle_list_cleaned, function(x)object.size(toString(x)))) size_without_html/size_with_html
Removes the indices in front of multiple entries as produced by fhir_crack()
when brackets are provided in
the design.
fhir_rm_indices( indexed_data_frame, brackets = c("<", ">"), columns = names(indexed_data_frame) )
fhir_rm_indices( indexed_data_frame, brackets = c("<", ">"), columns = names(indexed_data_frame) )
indexed_data_frame |
A data frame with indices for multiple entries as produced by |
brackets |
A character vector of length two defining the brackets that were used in |
columns |
A character vector of column names, indicating from which columns indices should be removed. Defaults to all columns. |
A data frame without indices.
#unserialize example bundles <- fhir_unserialize(bundles = example_bundles1) patients <- fhir_table_description(resource = "Patient") df <- fhir_crack(bundles = bundles, design = patients, brackets = c("[", "]")) df_indices_removed <- fhir_rm_indices(indexed_data_frame = df, brackets=c("[", "]"))
#unserialize example bundles <- fhir_unserialize(bundles = example_bundles1) patients <- fhir_table_description(resource = "Patient") df <- fhir_crack(bundles = bundles, design = patients, brackets = c("[", "]")) df_indices_removed <- fhir_rm_indices(indexed_data_frame = df, brackets=c("[", "]"))
Removes a given xml tag from xml objects represented in a fhir_bundle_xml, fhir_bundle_list or character vector.
fhir_rm_tag(x, tag) ## S4 method for signature 'character' fhir_rm_tag(x, tag) ## S4 method for signature 'fhir_bundle_xml' fhir_rm_tag(x, tag) ## S4 method for signature 'fhir_bundle_list' fhir_rm_tag(x, tag)
fhir_rm_tag(x, tag) ## S4 method for signature 'character' fhir_rm_tag(x, tag) ## S4 method for signature 'fhir_bundle_xml' fhir_rm_tag(x, tag) ## S4 method for signature 'fhir_bundle_list' fhir_rm_tag(x, tag)
x |
A fhir_bundle_xml or fhir_bundle_list object or a character vector containing xml objects. |
tag |
A character vector of length 1 containing the tag that should be removed, e.g. |
In the example Hello<div>Please<p>Remove Me</p></div>World!
one could for example remove the
tag p
, resulting in Hello<div>Please</div>World!
or remove the div
tag resulting in
Hello World!
.
An object of the same class as x
where all tags matching the tag
argument are removed.
#Example 1: Remove tag from xmls in a character vector string <- c("Hello<div>Please<p>Remove Me</p></div> World!", "A<div><div><p>B</p></div>C</div>D") fhir_rm_tag(x = string, tag = "p") #Example 2: Remove div tags in a single fhir bundle bundle <- fhir_unserialize(patient_bundles)[[1]] #example bundle contains html parts in div tags: cat(toString(bundle)) #remove html parts bundle_cleaned <- fhir_rm_tag(x = bundle, tag = "div") #have a look at the result cat(toString(bundle_cleaned)) #Example 3: Remove div tags in a list of fhir bundles bundle_list <- fhir_unserialize(patient_bundles) #remove html parts bundle_list_cleaned <- fhir_rm_tag(x = bundle_list, tag = "div") #check out how much the size of the bundle list is reduced by removing html size_with_html <- sum(sapply(bundle_list, function(x)object.size(toString(x)))) size_without_html <- sum(sapply(bundle_list_cleaned, function(x)object.size(toString(x)))) size_without_html/size_with_html
#Example 1: Remove tag from xmls in a character vector string <- c("Hello<div>Please<p>Remove Me</p></div> World!", "A<div><div><p>B</p></div>C</div>D") fhir_rm_tag(x = string, tag = "p") #Example 2: Remove div tags in a single fhir bundle bundle <- fhir_unserialize(patient_bundles)[[1]] #example bundle contains html parts in div tags: cat(toString(bundle)) #remove html parts bundle_cleaned <- fhir_rm_tag(x = bundle, tag = "div") #have a look at the result cat(toString(bundle_cleaned)) #Example 3: Remove div tags in a list of fhir bundles bundle_list <- fhir_unserialize(patient_bundles) #remove html parts bundle_list_cleaned <- fhir_rm_tag(x = bundle_list, tag = "div") #check out how much the size of the bundle list is reduced by removing html size_with_html <- sum(sapply(bundle_list, function(x)object.size(toString(x)))) size_without_html <- sum(sapply(bundle_list_cleaned, function(x)object.size(toString(x)))) size_without_html/size_with_html
Downloads a random sample of resources of a given resource type from a FHIR server. The resources can be further constrained using FHIR search parameters.
fhir_sample_resources( base_url, resource, parameters = NULL, username = NULL, password = NULL, token = NULL, add_headers = NULL, sample_size = 20, seed = 1, verbose = 1 )
fhir_sample_resources( base_url, resource, parameters = NULL, username = NULL, password = NULL, token = NULL, add_headers = NULL, sample_size = 20, seed = 1, verbose = 1 )
base_url |
A character vector of length one specifying the base URL of the FHIR server, e.g. |
resource |
A character vector of length one or fhir_resource_type object with the resource type to be downloaded, e.g. |
parameters |
Optional. Either a length 1 character vector containing properly formatted FHIR search parameters, e.g.
|
username |
A character vector of length one containing the username for basic authentication. |
password |
A character vector of length one containing the password for basic authentication. |
token |
A character vector of length one or object of class httr::Token, for bearer token authentication (e.g. OAuth2). See |
add_headers |
A named character vector of custom headers to add to the HTTP request, e.g. |
sample_size |
A integer of length 1 containing the number of resources to sample. |
seed |
A integer of length 1 containing the seed for the random generator. |
verbose |
An integer of length 1 containing the level of verbosity. Defaults to 1. |
This function performs three steps to draw a random sample of resources from a FHIR server:
Count how many resources matching the type resource
and the search parameters in parameters
are found on the server. This is done to assert that the desired sample_size
is bigger than the number of resources it is drawn from. This step can also be performed individually using fhir_count_resource()
.
Extract the resource (aka logical) IDs of all requested resources (without downloading the resources completely).
This step can be also be performed individually using fhir_get_resource_ids()
Draw a random sample of size sample_size
from the vector of resource IDs and download the corresponding set of resources from the server.
This can also be done individually using fhir_sample_resources_by_ids()
The actual download of the resources is done by fhir_get_resources_by_ids()
. This function will attempt to download the resources using a
FHIR search request via POST where the IDs are part of the body. See fhir_search()
for details. If this fails
(e.g. because the server doesn't allow POST operations), the function falls back on a GET request. If the set of IDs is too long to fit
into one GET request (i.e. if the request gets longer than 2083 characters), it will be spread across several requests.
For more information on authentication options, please see the help page of fhir_search()
A fhir_bundle_list containing randomly sampled resources.
fhir_search()
, fhir_sample_resources_by_ids()
, fhir_get_resources_by_ids()
, fhir_count_resource()
#the try({}, silent = TRUE) statement is only there to catch errors when the server is down #you can skip it when the server is reachable try({ #how many resources are on the server? count <- fhir_count_resource( base_url = 'https://hapi.fhir.org/baseR4', resource = "Patient", parameters = "gender=female") #randomly sample 30 of them bundles <- fhir_sample_resources( base_url = 'https://hapi.fhir.org/baseR4', resource = "Patient", parameters = "gender=female", sample_size = 30, seed = 1) bundles }, silent = TRUE)
#the try({}, silent = TRUE) statement is only there to catch errors when the server is down #you can skip it when the server is reachable try({ #how many resources are on the server? count <- fhir_count_resource( base_url = 'https://hapi.fhir.org/baseR4', resource = "Patient", parameters = "gender=female") #randomly sample 30 of them bundles <- fhir_sample_resources( base_url = 'https://hapi.fhir.org/baseR4', resource = "Patient", parameters = "gender=female", sample_size = 30, seed = 1) bundles }, silent = TRUE)
Download a random sample of resources from a vector of resource IDs.
fhir_sample_resources_by_ids( base_url, resource, ids, id_param = "_id", username = NULL, password = NULL, token = NULL, add_headers = NULL, sample_size = 20, seed = 1, verbose = 1 )
fhir_sample_resources_by_ids( base_url, resource, ids, id_param = "_id", username = NULL, password = NULL, token = NULL, add_headers = NULL, sample_size = 20, seed = 1, verbose = 1 )
base_url |
A character vector of length one specifying the base URL of the FHIR server, e.g. |
resource |
A character vector of length one or fhir_resource_type object with the resource type to be downloaded e.g. |
ids |
A character vector containing the IDs from which to sample. |
id_param |
A character vector of length one containing the FHIR Search parameter belonging to the ids in |
username |
A character vector of length one containing the username for basic authentication. |
password |
A character vector of length one containing the password for basic authentication. |
token |
A character vector of length one or object of class httr::Token, for bearer token authentication (e.g. OAuth2). See |
add_headers |
A named character vector of custom headers to add to the HTTP request, e.g. |
sample_size |
A integer of length 1 containing the number of resources to sample. |
seed |
A integer of length 1 containing the seed for the random generator. |
verbose |
An integer of length 1 containing the level of verbosity. Defaults to 1. |
This function takes a character vector ids
containing logical Ids of resources of a given type (specified in resource
) on a
FHIR server (specified in base_url
) and downloads a random sample of size sample_size
of the corresponding resources from the server.
Internally, the download of the resources is done by fhir_get_resources_by_ids()
. This function will attempt to download the resources using a
FHIR search request via POST where the IDs are part of the body. See fhir_search()
for details. If this fails
(e.g. because the server doesn't allow POST operations), the function falls back on a GET request. If the set of IDs is too long to fit
into one GET request (i.e. if the request gets longer than 2083 characters), it will be spread across several requests.
For more information on authentication options, please see the help page of 'fhir_search()
A list of bundles containing sampled resources.
fhir_search()
, fhir_sample_resources()
, fhir_get_resources_by_ids()
, fhir_count_resource()
#the try({}, silent = TRUE) statement is only there to catch errors when the server is down #you can skip it when the server is reachable try({ #find IDs of all resources representing Homer Simpson ids <- fhir_get_resource_ids( base_url = 'https://hapi.fhir.org/baseR4', resource = "Patient", parameters = "name=Homer&name=Simpson") #Sample 10 of them bundles <- fhir_sample_resources_by_ids( base_url = 'https://hapi.fhir.org/baseR4', resource = "Patient", ids = ids, sample_size = 10, seed = 1) #Have a look at the samples fhir_crack( bundles, fhir_table_description( resource = "Patient", cols = list( ID = "id", given = "name/given", family = "name/family"))) }, silent = TRUE)
#the try({}, silent = TRUE) statement is only there to catch errors when the server is down #you can skip it when the server is reachable try({ #find IDs of all resources representing Homer Simpson ids <- fhir_get_resource_ids( base_url = 'https://hapi.fhir.org/baseR4', resource = "Patient", parameters = "name=Homer&name=Simpson") #Sample 10 of them bundles <- fhir_sample_resources_by_ids( base_url = 'https://hapi.fhir.org/baseR4', resource = "Patient", ids = ids, sample_size = 10, seed = 1) #Have a look at the samples fhir_crack( bundles, fhir_table_description( resource = "Patient", cols = list( ID = "id", given = "name/given", family = "name/family"))) }, silent = TRUE)
Writes a list of FHIR bundles as numbered xml files into a directory.
fhir_save(bundles, directory)
fhir_save(bundles, directory)
bundles |
A list of xml objects representing the FHIR bundles. |
directory |
A character vector of length one containing the path to the folder to store the data in. |
#unserialize example bundle bundles <- fhir_unserialize(medication_bundles) #save all bundles to temporary directory fhir_save(bundles, directory = tempdir()) #save only two bundles (the second and the third) to temporary directory fhir_save(bundles[c(2,3)], directory = tempdir())
#unserialize example bundle bundles <- fhir_unserialize(medication_bundles) #save all bundles to temporary directory fhir_save(bundles, directory = tempdir()) #save only two bundles (the second and the third) to temporary directory fhir_save(bundles[c(2,3)], directory = tempdir())
Writes a fhir_design for use with fhir_crack()
to an xml file.
fhir_save_design(design, file = "design.xml")
fhir_save_design(design, file = "design.xml")
design |
A fhir_design object. See |
file |
A string specifying the file to write to, defaults to writing 'design.xml' into the current working directory. |
fhir_design()
, fhir_table_description()
, fhir_load_design()
#create and save design table_desc1 <- fhir_table_description( resource = 'Patient', cols = c( id = 'id', # column names with xpaths name = 'name/family', gender = 'gender' ), sep = ':::', brackets = c('[', ']'), rm_empty_cols = FALSE, format = 'compact', keep_attr = FALSE ) table_desc2 <- fhir_table_description( resource = 'Observation', cols = c( 'code/coding/system', # only xpaths 'code/coding/code' ) ) design <- fhir_design( Patients = table_desc1, Observations = table_desc2 ) fhir_save_design(design = design, file = tempfile())
#create and save design table_desc1 <- fhir_table_description( resource = 'Patient', cols = c( id = 'id', # column names with xpaths name = 'name/family', gender = 'gender' ), sep = ':::', brackets = c('[', ']'), rm_empty_cols = FALSE, format = 'compact', keep_attr = FALSE ) table_desc2 <- fhir_table_description( resource = 'Observation', cols = c( 'code/coding/system', # only xpaths 'code/coding/code' ) ) design <- fhir_design( Patients = table_desc1, Observations = table_desc2 ) fhir_save_design(design = design, file = tempfile())
Downloads all FHIR bundles of a FHIR search request from a FHIR server by iterating through the bundles. Search via GET and POST is possible, see Details.
fhir_search( request = fhir_current_request(), body = NULL, username = NULL, password = NULL, token = NULL, add_headers = NULL, max_bundles = Inf, verbose = 1, delay_between_attempts = c(1, 3, 9, 27, 81), log_errors = NULL, save_to_disc = NULL, delay_between_bundles = 0, rm_tag = "div", stop_on_error = 0 )
fhir_search( request = fhir_current_request(), body = NULL, username = NULL, password = NULL, token = NULL, add_headers = NULL, max_bundles = Inf, verbose = 1, delay_between_attempts = c(1, 3, 9, 27, 81), log_errors = NULL, save_to_disc = NULL, delay_between_bundles = 0, rm_tag = "div", stop_on_error = 0 )
request |
An object of class fhir_url or a character vector of length one containing the full FHIR search request. It is
recommended to explicitly create the request via |
body |
A character vector of length one or object of class |
username |
A character vector of length one containing the username for basic authentication. |
password |
A character vector of length one containing the password for basic authentication. |
token |
A character vector of length one or object of class httr::Token, for bearer token authentication (e.g. OAuth2). See |
add_headers |
A named character vector of custom headers to add to the HTTP request, e.g. |
max_bundles |
Maximal number of bundles to get. Defaults to Inf meaning all available bundles are downloaded. |
verbose |
An integer vector of length one. If 0, nothing is printed, if 1, only finishing message is printed, if > 1, downloading progress will be printed. Defaults to 1. |
delay_between_attempts |
A numeric vector specifying the delay in seconds between attempts of reaching the server
that |
log_errors |
Either |
save_to_disc |
Either |
delay_between_bundles |
A numeric scalar specifying a time in seconds to wait between pages of the search result, i.e. between downloading the current bundle and the next bundle. This can be used to avoid choking a weak server with too many requests to quickly. Defaults to zero. |
rm_tag |
Character vector of length 1 defining an xml tag of elements that will removed from the bundle automatically.
Defaults to |
stop_on_error |
Controls error handling for server requests
|
fhir_search
allows for two types of search request:
FHIR search via GET:
This is the more common approach. All information on which resources to download is contained in the URL
that is send to the server (request
argument). This encompasses the base url of the server, the resource type and possible
search parameters to further qualify the search (see fhir_url()
). The search via GET is the default and performed whenever
the argument body
is NULL.
FHIR search via POST:
This option should only be used when the parameters make the search URL so long the server might deny it
because it exceeds the allowed length. In this case the search parameters (everything that would usually follow the resource type
after the ?
) can be transferred to a body of type "application/x-www-form-urlencoded"
and send via POST. If you provide a body in
fhir_search()
, the url in request
should only contain the base URL and the resource type.
The function will automatically amend it with _search
and perform a POST.
There are several ways of authentication implemented in fhir_search()
. If you don't need any authentication,
just leave the arguments described in the following at their default values of NULL
.
Basic Authentication: Provide the username
and the password
for basic authentication in the respective arguments.
Token Authentication: Provide a token in the argument token
, either as a character vector of length one or as as an object of class
httr::Token. You can use the function fhir_authenticate()
to create this object.
Per default, the underlying HTTP requests are equipped with Accept and Authorization headers. If you need to pass additional headers,
e.g. cookies for authentication or other custom headers, you can add these to the request as a named character vector using the
add_headers
argument.
FHIR resources can contain a considerable amount of html code (e.g. in a narrative object),
which is often created by the server for example to provide a human-readable summary of the resource.
This data is usually not the aim of structured statistical analysis, so in the default setting fhir_search()
will remove the html
parts immediately after download to reduce memory usage (on a hapi server typically by around 30%, see fhir_rm_div()
).
The memory gain is payed with a runtime increase of 10%-20%. The html removal can be disabled by setting rm_tag = NULL
to increase speed at the cost of increased memory usage.
A fhir_bundle_list when save_to_disc = NULL
(the default), else NULL
.
Creating a FHIR search request: fhir_url()
and fhir_body()
(for POST based search)
OAuth2 Authentication: fhir_authenticate()
Saving/reading bundles from disc: fhir_save()
and fhir_load()
Flattening the bundles: fhir_crack()
#the try({}, silent = TRUE) statement is only there to catch errors when the server is down #you can skip it when the server is reachable try({ ### Search with GET #create fhir search url request <- fhir_url(url = "https://server.fire.ly", resource = "Patient", parameters = c(gender="female")) #download bundles bundles <- fhir_search(request, max_bundles = 5) ### Search with POST (should actually be used for longer requests) request <- fhir_url(url = "https://server.fire.ly", resource = "Patient") body <- fhir_body(content = list(gender = "female")) bundles <- fhir_search(request = request, body = body, max_bundles = 5) }, silent = TRUE)
#the try({}, silent = TRUE) statement is only there to catch errors when the server is down #you can skip it when the server is reachable try({ ### Search with GET #create fhir search url request <- fhir_url(url = "https://server.fire.ly", resource = "Patient", parameters = c(gender="female")) #download bundles bundles <- fhir_search(request, max_bundles = 5) ### Search with POST (should actually be used for longer requests) request <- fhir_url(url = "https://server.fire.ly", resource = "Patient") body <- fhir_body(content = list(gender = "female")) bundles <- fhir_search(request = request, body = body, max_bundles = 5) }, silent = TRUE)
Serializes FHIR bundles or resources to allow for saving in .rda or .RData format without losing integrity of pointers i.e. it turns a fhir_bundle_xml/fhir_resource_xml object into an fhir_bundle_serialized/fhir_resource_serialized object.
fhir_serialize(bundles) ## S4 method for signature 'fhir_bundle_xml' fhir_serialize(bundles) ## S4 method for signature 'fhir_bundle_serialized' fhir_serialize(bundles) ## S4 method for signature 'fhir_bundle_list' fhir_serialize(bundles) ## S4 method for signature 'fhir_resource_xml' fhir_serialize(bundles) ## S4 method for signature 'fhir_resource_serialized' fhir_serialize(bundles)
fhir_serialize(bundles) ## S4 method for signature 'fhir_bundle_xml' fhir_serialize(bundles) ## S4 method for signature 'fhir_bundle_serialized' fhir_serialize(bundles) ## S4 method for signature 'fhir_bundle_list' fhir_serialize(bundles) ## S4 method for signature 'fhir_resource_xml' fhir_serialize(bundles) ## S4 method for signature 'fhir_resource_serialized' fhir_serialize(bundles)
bundles |
A fhir_bundle, fhir_bundle_list or fhir_resource object. |
A fhir_bundle_xml, fhir_bundle_list or fhir_resource_xml object.
#example bundles are serialized, unserialize like this: bundles <- fhir_unserialize(medication_bundles) #Serialize like this: bundles_for_saving <- fhir_serialize(bundles) #works also on single bundles fhir_serialize(bundles[[1]])
#example bundles are serialized, unserialize like this: bundles <- fhir_unserialize(medication_bundles) #Serialize like this: bundles_for_saving <- fhir_serialize(bundles) #works also on single bundles fhir_serialize(bundles[[1]])
A fhir_table_description
holds the information fhir_crack()
needs to flatten (aka crack)
FHIR resources from a FHIR bundle. There should be one fhir_table_description
per resource type as
fhir_crack()
will create one data.frame/data.table per resource type in a bundle. See Details.
fhir_table_description( resource, cols = fhir_columns(), sep = ":::", brackets = character(), rm_empty_cols = FALSE, format = "compact", keep_attr = FALSE, style = deprecated() )
fhir_table_description( resource, cols = fhir_columns(), sep = ":::", brackets = character(), rm_empty_cols = FALSE, format = "compact", keep_attr = FALSE, style = deprecated() )
resource |
A character vector of length one or fhir_resource_type object indicating which resource type should be extracted. |
cols |
Optional. A fhir_columns object or something that can be coerced to one,
like a (named) character vector, a (named) list containing xpath expressions,
or a fhir_xpath_expression object. See |
sep |
A character of length one containing the separator string used for separating multiple entries in cells when |
brackets |
A character of length one or two used for the indices of multiple entries. The first one is the opening bracket
and the second one the closing bracket. Vectors of length one will be recycled.
Defaults to |
rm_empty_cols |
A logical of length one indicating whether empty columns should be removed from the resulting table or not. Defaults to |
format |
A character of length one indicating whether the resulting table should be cracked to a |
keep_attr |
A logical of length one indicating whether the attribute name of the respective element ( |
style |
A fhir_table_description
consists of
the following elements:
The resource element: Defines the resource type (e.g. Patient
or Observation
). See fhir_resource_type()
.
The cols element: Contains the column names and XPath expressions defining the columns to extract.
If this element is empty, fhir_crack()
will extract all available elements of the resource and name the
columns automatically. See fhir_columns()
.
The sep element: A character of length one containing the separator string used for separating multiple entries in cells.
The brackets element: A character of length one or two used for the indices of multiple entries. The first one is the opening bracket
and the second one the closing bracket. Vectors of length one will be recycled.
Defaults to character(0)
, i.e. no brackets, meaning that multiple entries won't be indexed.
The rm_empty_cols element: A logical of length one indicating whether empty columns should be removed in the resulting table or not. Defaults to FALSE
.
The format element: A character of length one indicating whether the resulting table should be cracked to a wide
or compact
format.
wide
means multiple entries will be distributed over several columns with indexed names. compact
means multiple entries will be pasted into one cell/column separated by sep
.
Defaults to compact
.
The keep_attr element: A logical of length one indicating whether the attribute name of the respective element (@value
in most cases)
should be attached to the name of the variable in the resulting table. Defaults to FALSE
.
A full fhir_table_description
looks for example like this:
fhir_resource_type: Patient fhir_columns: column name | xpath expression ------------------------ name | name/family gender | gender id | id sep: ':::' brackets: '[', ']' rm_empty_cols: FALSE format: 'compact' keep_attr: FALSE
An object of class fhir_table_description.
# a minimal table description fhir_table_description( resource = "Patient" ) # named list for cols fhir_table_description( resource = "Patient", cols = list( id = "id", name = "name/family", gender = "gender" ) ) #unnamed character for cols, colnames are generated automatically fhir_table_description( resource = "Patient", cols = c( "id", "name/family", "gender" ) ) # named character for cols, and overwritten default for other arguments fhir_table_description( resource = "Patient", cols = c( id = "id", name = "name/family", gender = "gender" ), brackets = c("[", "]"), rm_empty_cols = TRUE, format = "wide" ) # no column arguments is given -> creates a column for all available elements fhir_table_description( resource = "Patient", sep = " <~> ", brackets = c("<<<", ">>>"), rm_empty_cols = FALSE, format = "wide" )
# a minimal table description fhir_table_description( resource = "Patient" ) # named list for cols fhir_table_description( resource = "Patient", cols = list( id = "id", name = "name/family", gender = "gender" ) ) #unnamed character for cols, colnames are generated automatically fhir_table_description( resource = "Patient", cols = c( "id", "name/family", "gender" ) ) # named character for cols, and overwritten default for other arguments fhir_table_description( resource = "Patient", cols = c( id = "id", name = "name/family", gender = "gender" ), brackets = c("[", "]"), rm_empty_cols = TRUE, format = "wide" ) # no column arguments is given -> creates a column for all available elements fhir_table_description( resource = "Patient", sep = " <~> ", brackets = c("<<<", ">>>"), rm_empty_cols = FALSE, format = "wide" )
fhir_crack()
A fhir_table_description
holds the information fhir_crack()
needs to flatten (aka crack) FHIR resources from a FHIR bundle and
is created with its constructor function fhir_table_description()
.
Each fhir_table_description
describes a table for a specific resource type as fhir_crack()
will create one data.frame/data.table
per resource type. See Details.
A fhir_table_description
consists of
the following elements:
The resource element: Defines the resource type (e.g. Patient
or Observation
). See fhir_resource_type()
.
The cols element: Contains the column names and XPath expressions defining the columns to extract.
If this element is empty, fhir_crack()
will extract all available elements of the resource and name the
columns automatically. See fhir_columns()
.
The sep element: A character of length one containing the separator string used for separating multiple entries in cells.
The brackets element: A character of length one or two used for the indices of multiple entries. The first one is the opening bracket
and the second one the closing bracket. Vectors of length one will be recycled.
Defaults to character(0)
, i.e. no brackets, meaning that multiple entries won't be indexed.
The rm_empty_cols element: A logical of length one indicating whether empty columns should be removed in the resulting table or not. Defaults to FALSE
.
The format element: A character of length one indicating whether the resulting table should be cracked to a wide
or compact
format.
wide
means multiple entries will be distributed over several columns with indexed names. compact
means multiple entries will be pasted into one cell/column separated by sep
.
Defaults to compact
.
The keep_attr element: A logical of length one indicating whether the attribute name of the respective element (@value
in most cases)
should be attached to the name of the variable in the resulting table. Defaults to FALSE
.
A full fhir_table_description
looks for example like this:
fhir_resource_type: Patient fhir_columns: column name | xpath expression ------------------------ name | name/family gender | gender id | id sep: ':::' brackets: '[', ']' rm_empty_cols: FALSE format: 'compact' keep_attr: FALSE
resource
An object of class fhir_resource_type defining the resource type that should be extracted.
cols
An object of class fhir_columns describing which columns should be created and how.
If this is an empty fhir_columns object, the call to fhir_crack()
will extract all available
elements and put them in automatically named columns.
sep
A character of length one containing the separator string used for separating multiple entries in cells when format = "compact"
.
ignored when format = "wide"
.
brackets
A character of length one or two used for the indices of multiple entries. The first one is the opening bracket
and the second one the closing bracket. Vectors of length one will be recycled.
Defaults to character(0)
, i.e. no brackets, meaning that multiple entries won't be indexed.
rm_empty_cols
A logical of length one indicating whether empty columns should be removed from the resulting table or not. Defaults to FALSE.
format
A character of length one indicating whether the resulting table should be cracked to a wide
or compact
format.
wide
means multiple entries will be distributed over several columns with indexed names. compact
means multiple entries will be pasted into one cell/column separated by sep
.
Defaults to compact
.
keep_attr
A logical of length one indicating whether the attribute name of the respective element (@value
in most cases)
should be attached to the name of the variable in the resulting table. Defaults to FALSE
fhir_resource_type()
,fhir_columns()
, fhir_design()
, fhir_crack()
This function takes a wide table as created by fhir_crack()
with format="wide"
and creates the tree structure implicit in the
column names of the tables. It is useful to get an overview over the implied structure when planning to create
FHIR bundles from this table using fhir_build_bundle()
.
fhir_tree( table, brackets, resource = "Resource", keep_attr = FALSE, keep_ids = FALSE, skip_one = FALSE, format = "plain", prompt = ": " )
fhir_tree( table, brackets, resource = "Resource", keep_attr = FALSE, keep_ids = FALSE, skip_one = FALSE, format = "plain", prompt = ": " )
table |
A data.frame or data.table as produced by |
brackets |
A character vector of length two. The brackets used in the table. |
resource |
A character vector of length one or fhir_resource_type object indicating which resource type the table is build from. |
keep_attr |
A logical vector of length one indicating whether attributes should be displayed or not.
Only used for formats |
keep_ids |
A logical vector of length one indicating whether indices should be displayed or not.
Only used for formats |
skip_one |
A logical vector of length one indicating whether first index 1 should be displayed or not.
Only used for formats |
format |
The format of the tree. One of |
prompt |
A character vector of length one use as prompt
Only used for formats |
A string that can be used with cat()
or can be written to a text file.
fhir_cast()
, fhir_build_bundle()
#' #unserialize example bundles <- fhir_unserialize(bundles = example_bundles1) #crack fhir resources table_desc <- fhir_table_description( resource = "Patient", brackets = c("[", "]"), sep = " ", format = "wide" ) df <- fhir_crack(bundles = bundles, design = table_desc) ###show tree #plain format cat(fhir_tree( table = df, brackets = c("[", "]"), resource = "Patient" ) ) #fancy format with indices cat(fhir_tree( table = df, brackets = c("[", "]"), resource = "Patient", format = "fancy", keep_ids = TRUE ) ) #xml format cat(fhir_tree( table = df, brackets = c("[", "]"), resource = "Patient", format = "xml" ) )
#' #unserialize example bundles <- fhir_unserialize(bundles = example_bundles1) #crack fhir resources table_desc <- fhir_table_description( resource = "Patient", brackets = c("[", "]"), sep = " ", format = "wide" ) df <- fhir_crack(bundles = bundles, design = table_desc) ###show tree #plain format cat(fhir_tree( table = df, brackets = c("[", "]"), resource = "Patient" ) ) #fancy format with indices cat(fhir_tree( table = df, brackets = c("[", "]"), resource = "Patient", format = "fancy", keep_ids = TRUE ) ) #xml format cat(fhir_tree( table = df, brackets = c("[", "]"), resource = "Patient", format = "xml" ) )
Unserializes FHIR resources or bundles that have been serialized to allow for saving in .rda or .RData format, i.e. it turns a fhir_bundle_serialized/fhir_resource_serialized object into an fhir_bundle_xml/fhir_resource_xml object.
fhir_unserialize(bundles) ## S4 method for signature 'fhir_bundle_xml' fhir_unserialize(bundles) ## S4 method for signature 'fhir_bundle_serialized' fhir_unserialize(bundles) ## S4 method for signature 'fhir_resource_xml' fhir_unserialize(bundles) ## S4 method for signature 'fhir_resource_serialized' fhir_unserialize(bundles) ## S4 method for signature 'fhir_bundle_list' fhir_unserialize(bundles)
fhir_unserialize(bundles) ## S4 method for signature 'fhir_bundle_xml' fhir_unserialize(bundles) ## S4 method for signature 'fhir_bundle_serialized' fhir_unserialize(bundles) ## S4 method for signature 'fhir_resource_xml' fhir_unserialize(bundles) ## S4 method for signature 'fhir_resource_serialized' fhir_unserialize(bundles) ## S4 method for signature 'fhir_bundle_list' fhir_unserialize(bundles)
bundles |
A fhir_bundle, fhir_bundle_list or fhir_resource object. |
A fhir_bundle_serialized, fhir_bundle_list or fhir_resource_serializedobject.
#unserialize bundle list fhir_unserialize(patient_bundles) #unserialize single bundle fhir_unserialize(patient_bundles[[1]])
#unserialize bundle list fhir_unserialize(patient_bundles) #unserialize single bundle fhir_unserialize(patient_bundles[[1]])
This function creates an object of class fhir_url which mostly represents a URL-encoded URL for a FHIR search request. A valid Search URL contains a base URL and a resource type and may contain additional search parameters. For more info on FHIR search see https://www.hl7.org/fhir/search.html.
fhir_url(url, resource, parameters, url_enc = TRUE) ## S4 method for signature 'character,missing,missing' fhir_url(url, url_enc = TRUE) ## S4 method for signature 'character,character,missing' fhir_url(url, resource, url_enc = TRUE) ## S4 method for signature 'character,character,character' fhir_url(url, resource, parameters, url_enc = TRUE) ## S4 method for signature 'character,character,list' fhir_url(url, resource, parameters, url_enc = TRUE)
fhir_url(url, resource, parameters, url_enc = TRUE) ## S4 method for signature 'character,missing,missing' fhir_url(url, url_enc = TRUE) ## S4 method for signature 'character,character,missing' fhir_url(url, resource, url_enc = TRUE) ## S4 method for signature 'character,character,character' fhir_url(url, resource, parameters, url_enc = TRUE) ## S4 method for signature 'character,character,list' fhir_url(url, resource, parameters, url_enc = TRUE)
url |
A character of length one specifying either the full search request,
e.g. |
resource |
A character of length one or fhir_resource_type object with the resource type to be searched, e.g. |
parameters |
Optional. Either a length 1 character containing properly formatted FHIR search parameters, e.g.
|
url_enc |
Should the url be URL-encoded? Defaults to |
You can use this function in two ways. If you provide just one string in the argument url with the full FHIR search request, this string
will be taken as a full FHIR search request. If you also provide the arguments resource
and/or parameters
, the string in url
will be taken
as the base url of your FHIR server and the arguments will be concatenated appropriately to form the full request. See examples.
Note that only the latter approach does a validity check on the resource type!
You can disable URL-encoding by setting url_enc=FALSE
.
An object of class fhir_url
#provide full FHIR search request fhir_url(url = "http://hapi.fhir.org/baseR4/Patient?gender=male&_summary=count") #provide base url and resource type fhir_url( url = "http://hapi.fhir.org/baseR4", resource = "Patient" ) #parameters in one string fhir_url( url = "http://hapi.fhir.org/baseR4", resource = "Patient", parameters = "gender=male&_summary=count" ) #parameters as a named character fhir_url( url = "http://hapi.fhir.org/baseR4", resource = "Patient", parameters = c("gender" = "male", "_summary" = "count") ) #parameters as a named list fhir_url( url = "http://hapi.fhir.org/baseR4", resource = "Patient", parameters = list("gender" = "male", "_summary" = "count") )
#provide full FHIR search request fhir_url(url = "http://hapi.fhir.org/baseR4/Patient?gender=male&_summary=count") #provide base url and resource type fhir_url( url = "http://hapi.fhir.org/baseR4", resource = "Patient" ) #parameters in one string fhir_url( url = "http://hapi.fhir.org/baseR4", resource = "Patient", parameters = "gender=male&_summary=count" ) #parameters as a named character fhir_url( url = "http://hapi.fhir.org/baseR4", resource = "Patient", parameters = c("gender" = "male", "_summary" = "count") ) #parameters as a named list fhir_url( url = "http://hapi.fhir.org/baseR4", resource = "Patient", parameters = list("gender" = "male", "_summary" = "count") )
Objects of this class are basically strings (character vectors of length one) representing
a URL. They are usually url encoded. See fhir_url()
for how to build them.
This function takes a character vector, checks whether it contains valid XPath (1.0) expressions
and returns it as an fhir_xpath_expression object. These objects are used in fhir_parameters
objects.
fhir_xpath_expression(expression)
fhir_xpath_expression(expression)
expression |
A character vector of the XPath expressions |
A XPath expression object
fhir_xpath_expression(c("//Patient", "name/given"))
fhir_xpath_expression(c("//Patient", "name/given"))
fhir_columns
class.An S4 class for xpath_expressions
Objects of this class are essentially character vectors, but can only be valid
XPath (1.0) expressions.
They are mostly used in the fhir_columns
class.
These data examples can be used to explore some of the functions from the fhircrackr package when direct access to a FHIR server is not possible.
All example data sets are fhir_bundle_lists containing fhir_bundle_serialized objects
representing FHIR bundles as returned by fhir_search()
. They have to be unserialized (once per R session),
before you can work with them!
medication_bundles patient_bundles
medication_bundles patient_bundles
An object of class fhir_bundle_list
of length 3.
An object of class fhir_bundle_list
of length 2.
medication_bundles
contains 3 bundles with MedicationStatement resources representing Medications with Snomed CT code
429374003 and the respective Patient resources that are linked to these MedicationStatements.
patient_bundles
contains 2 bundles with Patient resources.
The data sets are generated by the following code:
medication_bundles (Downloaded 10-05-21)
search_request <- fhir_url(url = "https://hapi.fhir.org/baseR4", resource = "MedicationStatement", parameters = c("code" = "http://snomed.info/ct|429374003", "_include" = "MedicationStatement:subject")) bundles <- fhir_search(request = search_request, max_bundles = 3) medication_bundles <- fhir_serialize(bundles = bundles)
patient_bundles (Downloaded 10-05-21)
bundles <- fhir_search(request="https://hapi.fhir.org/baseR4/Patient", max_bundles=2, verbose = 0) patient_bundles <- fhir_serialize(bundles = bundles)
#unserialize xml objects before doing anything else with them! fhir_unserialize(bundles = medication_bundles) #unserialize xml objects before doing anything else with them! fhir_unserialize(bundles = patient_bundles)
#unserialize xml objects before doing anything else with them! fhir_unserialize(bundles = medication_bundles) #unserialize xml objects before doing anything else with them! fhir_unserialize(bundles = patient_bundles)
Concatenates two strings to a path string correctly.
paste_paths(path1 = "w", path2 = "d", os = "LiNuX")
paste_paths(path1 = "w", path2 = "d", os = "LiNuX")
path1 |
A a character vector of length one specifying the left hand part of the resulting path. |
path2 |
A a character vector of length one specifying the right hand part of the resulting path. |
os |
A a character vector of length one specifying the operating system you're operating on: windows or linux. |
A a character vector of length one containing the concatenated path.
paste_paths(path1 = "data", path2 = "patients") paste_paths(path1 = "/data", path2 = "patients") paste_paths(path1 = "/data/", path2 = "patients") paste_paths(path1 = "/data", path2 = "/patients") paste_paths(path1 = "/data/", path2 = "/patients/") paste_paths(path1 = "data", path2 = "patients", os = "windows")
paste_paths(path1 = "data", path2 = "patients") paste_paths(path1 = "/data", path2 = "patients") paste_paths(path1 = "/data/", path2 = "patients") paste_paths(path1 = "/data", path2 = "/patients") paste_paths(path1 = "/data/", path2 = "/patients/") paste_paths(path1 = "data", path2 = "patients", os = "windows")
Concatenates two or more strings to a path string correctly.
pastep(..., list_of_paths = NULL, ext = NULL)
pastep(..., list_of_paths = NULL, ext = NULL)
... |
A Set of Path Strings. Only works if list_of_paths is NULL |
list_of_paths |
Either a vector or a list of paths strings |
ext |
An Extension to add at the end of the path |
A Character of length one, the combined path.
pastep('a', 'b', 'c', 'd') pastep(list_of_paths = list(paste0('/', letters, '/'), as.character(1:13))) pastep(list_of_paths = c(letters, as.character(1:13))) pastep(list_of_paths = c(letters, as.character(1:13)), ext = '.txt') pastep(list_of_paths = c(letters, as.character(1:13)), ext = '_dat.txt')
pastep('a', 'b', 'c', 'd') pastep(list_of_paths = list(paste0('/', letters, '/'), as.character(1:13))) pastep(list_of_paths = c(letters, as.character(1:13))) pastep(list_of_paths = c(letters, as.character(1:13)), ext = '.txt') pastep(list_of_paths = c(letters, as.character(1:13)), ext = '_dat.txt')
These data examples are simple examples to try out POSTing/PUTing resources to a server. See Source for how the xml versions look.
transaction_bundle_example example_resource1 example_resource2 example_resource3
transaction_bundle_example example_resource1 example_resource2 example_resource3
An object of class fhir_bundle_serialized
of length 1277.
An object of class fhir_resource_serialized
of length 267.
An object of class fhir_resource_serialized
of length 290.
An object of class fhir_resource_serialized
of length 608.
transaction_bundle_example
contains 1 transaction bundle with 2 Patient resources.
example_resource1
contains 1 patient resource without id for POSTing
example_resource2
contains 1 patient resource with id for PUTing
example_resource3
contains 1 Medication resource with an id xml attribute
transaction_bundle_example
<Bundle> <type value='transaction'/> <entry> <resource> <Patient> <id value='id1'/> <address> <use value='home'/> <city value='Amsterdam'/> <type value='physical'/> <country value='Netherlands'/> </address> <name> <given value='Marie'/> </name> </Patient> </resource> <request> <method value='POST'/> <url value='Patient'/> </request> </entry> <entry> <resource> <Patient> <id value='id3'/> <address> <use value='home'/> <city value='Berlin'/> </address> <address> <use value='work'/> <city value='London'/> <type value='postal'/> <country value='England'/> </address> <address> <type value='postal'/> <country value='France'/> </address> <name> <given value='Frank'/> </name> <name> <given value='Max'/> </name> </Patient> </resource> <request> <method value='POST'/> <url value='Patient'/> </request> </entry> </Bundle>
example_resource1
<Patient> <name> <given value = 'Marie'/> </name> <gender value = 'female'/> <birthDate value = '1970-01-01'/> </Patient>
example_resource2
<Patient> <id value = '1a2b3c'/> <name> <given value = 'Marie'/> </name> <gender value = 'female'/> <birthDate value = '1970-01-01'/> </Patient>
example_resource3
<Medication> <code> <coding> <system value="http://www.nlm.nih.gov/research/umls/rxnorm"/> <code value="1594660"/> <display value="Alemtuzumab 10mg/ml (Lemtrada)"/> </coding> </code> <ingredient id="1"> <itemReference> <reference value="Substance/5463"/> </itemReference> </ingredient> <ingredient id="2"> <itemReference> <reference value="Substance/3401"/> </itemReference> </ingredient> </Medication>
#unserialize xml objects before doing anything else with them! fhir_unserialize(bundles = transaction_bundle_example) #unserialize xml objects before doing anything else with them! fhir_unserialize(example_resource1) #unserialize xml objects before doing anything else with them! fhir_unserialize(example_resource2) #unserialize xml objects before doing anything else with them! fhir_unserialize(example_resource3)
#unserialize xml objects before doing anything else with them! fhir_unserialize(bundles = transaction_bundle_example) #unserialize xml objects before doing anything else with them! fhir_unserialize(example_resource1) #unserialize xml objects before doing anything else with them! fhir_unserialize(example_resource2) #unserialize xml objects before doing anything else with them! fhir_unserialize(example_resource3)