This project serves as a teaching resource for project pipelines within OS, which vary in complexity (demonstrated using branches), as well as serving as an investigation into inhaler prescribing behaviours surrounding the pandemic.
Documentation explaining and contextualising the code in this repository can be found in the README.md files alongside the code, as well as within code comments in the code files themselves.
This repository was created from the OpenSAFELY Research Template, and follows the same directory structure and best practices laid out by that template.
Where this repository differs from a standard research project is that in this repository, we have three branches (main, pipeline_2 and pipeline_3). These three branches represent different levels of complexity in the logic used for dataset selection, and the resulting analyses made possible by that.
mainis the first level of complexity: we select a 'simple' dataset of patients with certain diagnosis and medication histories, working with a single index date and considering a single interval of time.pipeline_2is the second level of complexity. In this scenario, we select three 'simple' datasets of patients, considering three intervals of time, to analyse differences inhaler prescribing behaviour across a broader time period.pipeline_3is the third level. In this pipeline, we select datasets of different cohorts of patients, with different medication and diagnosis histories, to analyse differences in inhaler prescribing behaviour across multiple time periods and across multiple cohort profiles.
In a standard OpenSAFELY research repository, all runnable research code would typically be in the main branch, and other branches would be used exclusively for development (with those branches being merged into main via a pull request once their development was complete). The usage of branches in this repository represents the stages a research project might go through over time, evolving from a something simple (as in this repository's main branch) through to involving more complex data selection and analysis (pipeline_2 and pipeline_3).
When working in OpenSAFELY, researchers don't ever have access to sensitive data. The real databases are only queried when jobs are submitted through the OpenSAFELY Jobs Site, and submitting a job every time one needs to debug an issue would be extremely time-intensive and difficult.
A dataset definition, when used in the generate-dataset action, is a function that takes in a database of patient records and outputs a dataset. During development, we fake the input to this function, typically using dummy data tables. We may optionally choose to fake the output too, as this output is what our analysis code takes as an input, and we need to test that code too.
When getting started, researchers often use ehrQL's built-in dummy data generation as-is, which is 'good enough' to enable development of dataset definition code. However, while ehrQL is able to output plausible data, it can't automatically determine what realistic data might look like, and so the autogenerated dummy data is usually insufficient to support downstream analysis code.
As a next step, it's possible to output ehrQL's autogenerated dummy tables (using the create-dummy-tables command), then augment that data with a custom script (often using codelists). This allows a researcher to ensure that the dummy tables contain enough of the features of interest (clinical events, medication histories, addresses with IMD data, and so on) to support downstream analysis. This data can then be used during development by passing in a command-line parameter to the generate-dataset action in the project.yaml. This is the approach used in this showcase project.
If working with a particularly complex dataset definition, it may be too cumbersome or time-consuming to engineer dummy tables that yield a suitable dataset once the dataset definition has selected a cohort from them. In this case, it can be useful to - instead of 'faking' the input data (the tables) - instead fake the output (the dataset itself). A researcher can write a custom script to generate a datset of patients that can support the downstream analysis, and then use that dataset as the input to the analysis (as opposed the actual output of their generate-dataset action). The downside here is that, during testing, running the whole pipeline will now not exercise the logic in the dataset definition file, because its output is being ignored (and the fake data substituted). To test the logic in the dataset definition, we recommend using assurance testing, which is used in each pipeline of this repository.
Details of the purpose and any published outputs from this project can be found at the link above.
The contents of this repository MUST NOT be considered an accurate or valid representation of the study or its purpose. This repository may reflect an incomplete or incorrect analysis with no further ongoing work. The content has ONLY been made public to support the OpenSAFELY open science and transparency principles and to support the sharing of re-usable code for other subsequent users. No clinical, policy or safety conclusions must be drawn from the contents of this repository.
The OpenSAFELY framework is a Trusted Research Environment (TRE) for electronic health records research in the NHS, with a focus on public accountability and research quality.
Read more at OpenSAFELY.org.
As standard, research projects have a MIT license.