cardinal_pythonlib.psychiatry.drugs¶
Original code copyright (C) 2009-2022 Rudolf Cardinal (rudolf@pobox.com).
This file is part of cardinal_pythonlib.
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
Drug information, with an emphasis on psychotropic drugs, including translating specific to generic names.
Examples
Test within Python:
from cardinal_pythonlib.psychiatry.drugs import *
drug_name_to_generic("UNKNOWN")
drug_name_to_generic("UNKNOWN", unknown_to_default=True)
drug_names_to_generic([
"citalopram", "Citalopram", "Cipramil", "Celexa",
"olanzepine", # typo
"dextroamphetamine",
"amitryptyline",
])
Antidepressants
As of 2018-07-01, this is a functional superset of the SLAM
antidepressant-finding SQL (see dep_med_v1
), though mainly a superset in
non-antidepressant respects; the only antidepressants it adds are:
- buproprion, maprotiline
The SLAM antidepressant finder finds:
- tricyclic (category)
- amitriptyline, clomipramine, dosulepin, doxepin, imipramine, lofepramine, nortriptyline, trimipramine
- mianserin, trazodone, phenelzine, isocarboxazid, tranylcypromine, moclobemide
- citalopram, escitalopram, fluoxetine, fluvoxamine, paroxetine, sertraline
- mirtazapine, reboxetine, venlafaxine, agomelatine, duloxetine
- flupentixol, tryptophan
Sorted, that is:
agomelatine
amitriptyline
citalopram
clomipramine
dosulepin
doxepin
duloxetine
escitalopram
fluoxetine
flupentixol
fluvoxamine
imipramine
isocarboxazid
lofepramine
mianserin
mirtazapine
moclobemide
nortriptyline
paroxetine
phenelzine
reboxetine
sertraline
tranylcypromine
trazodone
tricyclic
trimipramine
tryptophan
venlafaxine
Compare that against the output of:
[x.generic_name for x in all_drugs_where(slam_antidepressant_finder=True,
include_categories=True)]
Using this code from R via reticulate
Test within R:
# -------------------------------------------------------------------------
# Load libraries
# -------------------------------------------------------------------------
RUN_ONCE_ONLY <- '
library(devtools)
devtools::install_github("rstudio/reticulate") # get latest version
'
library(data.table)
library(reticulate)
# -------------------------------------------------------------------------
# Set up reticulate
# -------------------------------------------------------------------------
VENV <- "~/dev/venvs/cardinal_pythonlib" # or your preferred virtualenv
PYTHON_EXECUTABLE <- ifelse(
.Platform$OS.type == "windows",
file.path(VENV, "Scripts", "python.exe"), # Windows
file.path(VENV, "bin", "python") # Linux
)
reticulate::use_python(PYTHON_EXECUTABLE, required=TRUE)
# ... it is CRITICAL to use required=TRUE, or it might fail silently
# Unnecessary now reticulate::use_python() works:
#
# PYTHON_VERSION <- "python3.5"
# CARDINAL_PYTHONLIB_BASEDIR <- ifelse(
# .Platform$OS.type == "windows",
# file.path(VENV, "lib", "site-packages/cardinal_pythonlib"),
# file.path(VENV, "lib", PYTHON_VERSION, "site-packages/cardinal_pythonlib")
# )
# reticulate::use_virtualenv(VENV, required=TRUE)
#
# cpl_fileops <- reticulate::import_from_path("fileops", CARDINAL_PYTHONLIB_BASEDIR)
# cpl_drugs <- reticulate::import_from_path("drugs", file.path(CARDINAL_PYTHONLIB_BASEDIR, "psychiatry"))
#
# ... this is NOT WORKING properly; dotted imports via reticulate::import() fail; also, imports from
# within the Python code fail even if you use reticulate::import_from_path(); this suggests the virtualenv is not set up
# properly; use reticulate::use_python() instead.
# -------------------------------------------------------------------------
# Import Python modules
# -------------------------------------------------------------------------
cardinal_pythonlib <- reticulate::import("cardinal_pythonlib")
cpl_fileops <- reticulate::import("cardinal_pythonlib.fileops")
cpl_drugs <- reticulate::import("cardinal_pythonlib.psychiatry.drugs")
# -------------------------------------------------------------------------
# Do something useful
# -------------------------------------------------------------------------
testnames <- c("citalopram", "Cipramil", "Prozac", "fluoxetine")
# Works for simple variables:
cpl_drugs$drug_names_to_generic(testnames)
# Also works for data table replacements:
dt <- data.table(
subject = c("Alice", "Bob", "Charles", "Dawn", "Egbert", "Flora"),
drug = c("citalopram", "Cipramil", "Prozac", "fluoxetine", "Priadel", "Haldol")
)
dt[, drug_generic := cpl_drugs$drug_names_to_generic(drug)]
dt[, is_antidepressant := cpl_drugs$drug_names_match_criteria(
drug_generic,
names_are_generic=TRUE,
antidepressant=TRUE)]
dt[, is_antidepressant_not_ssri := cpl_drugs$drug_names_match_criteria(
drug_generic,
names_are_generic=TRUE,
antidepressant=TRUE,
ssri=FALSE)]
dt[, is_conventional_antidepressant := cpl_drugs$drug_names_match_criteria(
drug_generic,
names_are_generic=TRUE,
conventional_antidepressant=TRUE)]
dt[, slam_antidepressant_finder := cpl_drugs$drug_names_match_criteria(
drug_generic,
names_are_generic=TRUE,
slam_antidepressant_finder=TRUE,
include_categories=TRUE)]
Use for SQL finding
from typing import List
from cardinal_pythonlib.psychiatry.drugs import *
colname = "somecol"
antidepressants = all_drugs_where(conventional_antidepressant=True) # type: List[Drug]
antidep_sql_parts = [drug.sql_column_like_drug(colname) for drug in antidepressants]
antidep_sql = " OR ".join(antidep_sql_parts)
antipsychotics = all_drugs_where(antipsychotic=True) # type: List[Drug]
antipsy_sql_parts = [drug.sql_column_like_drug(colname) for drug in antipsychotics]
antipsy_sql = " OR ".join(antipsy_sql_parts)
alldrugs = all_drugs_where()
alldrug_sql_parts = [drug.sql_column_like_drug(colname) for drug in alldrugs]
alldrug_sql = " OR ".join(alldrug_sql_parts)
lithium = get_drug("lithium")
lithium_sql = lithium.sql_column_like_drug(colname)
# HOWEVER, NOTE THAT LITHIUM IS CURRENTLY OVER-INCLUSIVE and will include
# lithium chloride for LiDCO measurement.
-
class
cardinal_pythonlib.psychiatry.drugs.
Drug
(generic: Union[str, List[str]], alternatives: List[str] = None, category_not_drug: bool = False, add_preceding_wildcards: bool = True, add_preceding_word_boundary: bool = True, add_following_wildcards: bool = True, psychotropic: bool = None, antidepressant: bool = False, conventional_antidepressant: bool = False, ssri: bool = False, non_ssri_modern_antidepressant: bool = False, tricyclic_antidepressant: bool = False, tetracyclic_and_related_antidepressant: bool = False, monoamine_oxidase_inhibitor: bool = False, antipsychotic: bool = False, first_generation_antipsychotic: bool = False, second_generation_antipsychotic: bool = False, stimulant: bool = False, anticholinergic: bool = False, benzodiazepine: bool = False, z_drug: bool = False, non_benzodiazepine_anxiolytic: bool = False, gaba_a_functional_agonist: bool = False, gaba_b_functional_agonist: bool = False, mood_stabilizer: bool = False, antidiabetic: bool = False, sulfonylurea: bool = False, biguanide: bool = False, glifozin: bool = False, glp1_agonist: bool = False, dpp4_inhibitor: bool = False, meglitinide: bool = False, thiazolidinedione: bool = False, cardiovascular: bool = False, beta_blocker: bool = False, ace_inhibitor: bool = False, statin: bool = False, respiratory: bool = False, beta_agonist: bool = False, gastrointestinal: bool = False, proton_pump_inhibitor: bool = False, nonsteroidal_anti_inflammatory: bool = False, vitamin: bool = False, slam_antidepressant_finder: bool = False)[source]¶ Class to describe a specific drug, or a drug category.
Also embodies knowledge about brand names and common misspellings.
See the
DRUGS
list for example of use.Initialize and determine/store category knowledge.
alternatives
can include regexes (as text).We add front/back wildcards by default; this handles all situations like “depot X”, etc. We also add a preceding word boundary (after the wildcard); thus the usual transformation is
XXX
->.*XXX.*
.Parameters: - generic – generic name, or list of names
- alternatives – can include regexes (as text)
- category_not_drug – is this a drug category, not a specific drug?
- add_preceding_wildcards – when making a regex (etc.), add a wildcard to the start of all possibilities (generic + alternative names) that don’t already have one?
- add_preceding_word_boundary – when making a regex (etc.), add word boundaries to the start of all possibilities (generic + alternative names) that don’t already have one?
- add_following_wildcards – when making a regex (etc.), add a wildcard to the end of all possibilities (generic + alternative names) that don’t already have one?
- psychotropic – a psychotropic drug?
- antidepressant – an antidepressant?
- conventional_antidepressant – a traditional antidepressant?
- ssri – a selective serotonin reuptake inhibitor (SSRI)?
- non_ssri_modern_antidepressant – a non-SSRI “modern” antidepressant?
- tricyclic_antidepressant – a tricyclic?
- tetracyclic_and_related_antidepressant – a tetracyclic or related?
- monoamine_oxidase_inhibitor – a MAO-I?
- antipsychotic – an antipsychotic?
- first_generation_antipsychotic – an FGA?
- second_generation_antipsychotic – an SGA?
- stimulant – a psychostimulant?
- anticholinergic – an anticholinergic?
- benzodiazepine – a benzodiazepine?
- z_drug – a “Z” drug (e.g. zopiclone, zolpidem, …)
- non_benzodiazepine_anxiolytic – a non-BZ anxiolytic?
- gaba_a_functional_agonist – a GABA-A functional agonist?
- gaba_b_functional_agonist – a GABA-B functional agonist?
- mood_stabilizer – a “mood stabilizer”?
- antidiabetic – treats diabetes?
- sulfonylurea – a sulfonylurea (sulphonylurea), for diabetes?
- biguanide – a biguanide, for diabetes?
- glifozin – a glifozin, for diabetes?
- glp1_agonist – a GLP-1 agonist, for diabetes?
- dpp4_inhibitor – a DPP4 inhibitor, for diabetes?
- meglitinide – a meglitinide, for diabetes?
- thiazolidinedione – a thiazolidinedione, for diabetes?
- cardiovascular – a cardiovascular drug?
- beta_blocker – a beta adrenoceptor antagonist?
- ace_inhibitor – an ACE inhibitor?
- statin – a statin?
- respiratory – a respiratory drug?
- beta_agonist – a beta adrenoceptor agonist?
- gastrointestinal – a gastrointestinal drug?
- proton_pump_inhibitor – a PPI?
- nonsteroidal_anti_inflammatory – an NSAID?
- vitamin – a vitamin?
- slam_antidepressant_finder – a drug found by the SLAM antidepressant-finding code? (A bit specialized, this one!)
-
mixture
¶ is this a mixture of more than one drug? Will be set if more than one generic name is given.
Type: bool
-
all_generics
¶ list of all generic names in lower case
Type: List[str]
-
generic_name
¶ generic name (or combination name like
a_with_b
for mixtures ofa
andb
)
-
regex
¶ compiled case-insensitive regular expression to match possible names
-
name_matches
(name: str) → bool[source]¶ Detects whether the name that’s passed matches our knowledge of any of things that this drug might be called: generic name, brand name(s), common misspellings.
The parameter should be pre-stripped of edge whitespace.
-
regex
Returns a compiled regex for this drug.
-
regex_text
¶ Return regex text (yet to be compiled) for this drug.
-
static
regex_to_sql_like
(regex_text: str, single_wildcard: str = '_', zero_or_more_wildcard: str = '%') → List[str][source]¶ Converts regular expression text to a reasonably close fragment for the SQL
LIKE
operator.NOT PERFECT, but works for current built-in regular expressions.
Parameters: - regex_text – regular expression text to work with
- single_wildcard – SQL single wildcard, typically an underscore
- zero_or_more_wildcard – SQL “zero/one/many” wildcard, probably always a percent symbol
Returns: string for an SQL string literal
Raises: ValueError
for some regex text that it doesn’t understandproperly
-
sql_column_like_drug
(column_name: str) → str[source]¶ Returns SQL like
(column_name LIKE '%drugname1%' OR column_name LIKE '%drugname2%')
for the drug names that this Drug object knows about.
Parameters: column_name – column name, pre-escaped if necessary Returns: SQL fragment as above
-
sql_like_fragments
¶ Returns all the string literals to which a database column should be compared using the SQL
LIKE
operator, to match this drug.This isn’t as accurate as the regex, but
LIKE
can do less.LIKE
uses the wildcards?
and%
.
-
cardinal_pythonlib.psychiatry.drugs.
all_drugs_where
(sort=True, include_categories: bool = False, **criteria) → List[cardinal_pythonlib.psychiatry.drugs.Drug][source]¶ Find all drugs matching the specified criteria (see
drug_matches_criteria()
). Ifinclude_categories
is true, then drug categories (like “tricyclics”) are included as well as individual drugs.Pass keyword arguments such as
from cardinal_pythonlib.psychiatry.drugs import * non_ssri_antidep = all_drugs_where(antidepressant=True, ssri=False) print([d.generic_name for d in non_ssri_antidep]) conventional_antidep = all_drugs_where(conventional_antidepressant=True) print([d.generic_name for d in conventional_antidep])
-
cardinal_pythonlib.psychiatry.drugs.
drug_matches_criteria
(drug: cardinal_pythonlib.psychiatry.drugs.Drug, **criteria) → bool[source]¶ Determines whether a drug, passed as an instance of
Drug
, matches the specified criteria.Parameters:
-
cardinal_pythonlib.psychiatry.drugs.
drug_name_matches_criteria
(drug_name: str, name_is_generic: bool = False, include_categories: bool = False, **criteria) → bool[source]¶ Establish whether a single drug, passed by name, matches the specified criteria. See
drug_matches_criteria()
.
-
cardinal_pythonlib.psychiatry.drugs.
drug_name_to_generic
(drug_name: str, unknown_to_default: bool = False, default: str = None, include_categories: bool = False) → str[source]¶ Converts a drug name to the name of its generic equivalent.
-
cardinal_pythonlib.psychiatry.drugs.
drug_names_match_criteria
(drug_names: List[str], names_are_generic: bool = False, include_categories: bool = False, **criteria) → List[bool][source]¶ Establish whether multiple drugs, passed as a list of drug names, each matches the specified criteria. See
drug_matches_criteria()
.
-
cardinal_pythonlib.psychiatry.drugs.
drug_names_to_generic
(drugs: List[str], unknown_to_default: bool = False, default: str = None, include_categories: bool = False) → List[str][source]¶ Converts a list of drug names to their generic equivalents.
The arguments are as for
drug_name_to_generic()
but this function handles a list of drug names rather than a single one.Note in passing the following conversion of blank-type representations from R via
reticulate
, when using e.g. thedefault
parameter and storing results in adata.table()
character column:------------------------------ ---------------- To Python Back from Python ------------------------------ ---------------- [not passed, so Python None] "NULL" NULL "NULL" NA_character_ "NA" NA TRUE (logical) ------------------------------ ----------------
-
cardinal_pythonlib.psychiatry.drugs.
get_drug
(drug_name: str, name_is_generic: bool = False, include_categories: bool = False) → Optional[cardinal_pythonlib.psychiatry.drugs.Drug][source]¶ Converts a drug name to a
Drug
class.If you already have the generic name, you can get the Drug more efficiently by setting
name_is_generic=True
.Set
include_categories=True
to include drug categories (such as tricyclics) as well as individual drugs.