Skip to contents

Introduction

mmequiv provides tools for calculating standardized Morphine Milligram Equivalent (MME) doses for opioid medications in research settings. This vignette will help you understand the key functions and how to implement them in your research workflow.

Understanding MME Calculations

Calculating MME is a way to compare prescription opioid medication doses by converting different opioid medications to an equivalent morphine dose. This standardization is essential for researchers working with prescription opioid data, particularly in:

  • Population-level medication utilization studies
  • Pharmacoepidemiologic research
  • Claims-based analyses

mmequiv implements the same calculations used by the NIH HEAL MME Online Calculator, providing researchers with:

  • API access to the official calculator
  • Local calculation capabilities for large datasets
  • Several standardized definitions of daily MME

Finding Available Medications

To see which opioid medications can be used with mmequiv for MME calculation, use get_med_list():

# Get the full list of supported medications and their conversion factors
meds <- get_med_list()

# View first few rows
head(meds)
#>                                    med_name     cf
#> 1    Buprenorphine buccal film (mcg) buccal  0.039
#> 2  Buprenorphine patch (mcg/hr) transdermal  2.200
#> 3 Buprenorphine tablet/film (mg) sublingual 38.800
#> 4                          butorphanol (mg)  7.000
#> 5                              Codeine (mg)  0.150
#> 6                       Dihydrocodeine (mg)  0.250

If you’re looking for a specific medication, you can search using a partial name:

# Search for medications containing "oxy" in the name
search_meds("oxy")
#>              med_name  cf
#> 1   Oxycodone (mg) LA 1.5
#> 2 Oxymorphone (mg) LA 3.0
#> 3      Oxycodone (mg) 1.5
#> 4    Oxymorphone (mg) 3.0

Basic MME Calculation Using the NIH HEAL MME Online Calculator API

The core function in the package is calculate_mme.list(), which can calculate MME for one or more opioid medications for a single patient or for multiple different patients using the NIH HEAL MME Online Calculator API. To use it with data for a single patient, you’ll need to provide:

  1. A list of medications with dosage information
  2. Total therapy days (with each calendar day counted once)
  3. The observation window in days

Here’s a simple example:

# Create a medications list with two medications
meds_list <- list(
  list(
    medication_name = "Hydrocodone (mg)",
    dose = 10,
    doses_per_24_hours = 4,
    days_of_medication = 7
  ),
  list(
    medication_name = "Oxycodone (mg)",
    dose = 5,
    doses_per_24_hours = 2,
    days_of_medication = 5
  )
)

# Calculate MME with 7 therapy days and 14-day observation window
result <- calculate_mme(
  x = meds_list,
  therapy_days = 7,
  observation_window_days = 14
  )

calculate_mme()’s use_api argument is set to TRUE by default when providing data for a single patient.

Understanding the Results

Let’s examine the results of our calculation:

# Medication-level results
print(result$medications)
#>    medication_name dose doses_per_24_hours days_of_medication factor mme
#> 1 Hydrocodone (mg)   10                  4                  7    1.0 280
#> 2   Oxycodone (mg)    5                  2                  5    1.5  75
#>   single_day_mme
#> 1             40
#> 2             15

# MME definitions with buprenorphine
print(result$mme_definitions$with_buprenorphine)
#>   total_mme total_days     mme1     mme2     mme3 mme4
#> 1       355         12 29.58333 50.71429 25.35714   55

# MME definitions without buprenorphine
print(result$mme_definitions$without_buprenorphine)
#>   total_mme total_days     mme1     mme2     mme3 mme4
#> 1       355         12 29.58333 50.71429 25.35714   55

The results include:

  1. Patient Medication-level calculations: Each medication’s conversion factor, MME (total), and single-day MME.

  2. Patient-level summary calculations:

  • total_mme: Sum of MME across all the patient’s prescriptions
  • total_days: Sum of days across all the patient’s prescriptions
  • Four different MME/day definitions:
    • mme1: Total MME / Total Days Supply
    • mme2: Total MME / On-therapy Days
    • mme3: Total MME / Observation Window Days
    • mme4: Maximum Daily Dose (sum of single-day MME for all the patient’s prescriptions)

When to Use Local Calculations

The NIH HEAL MME Online Calculator currently has a rate limit of 50 requests per 15 minutes, where each calculation request is unique to a patient. You can use calculate_mme.list() with the use_api = FALSE, which performs the exact same calculations locally:

# Use local calculation (no API call)
calculate_mme(
  x = meds_list,
  therapy_days = 7, 
  observation_window_days = 14,
  use_api = FALSE
  )
#> $message
#> [1] "Processed medications (local calculation)"
#> 
#> $therapy_obs_window_with
#> $therapy_obs_window_with$therapy_days
#> [1] 7
#> 
#> $therapy_obs_window_with$observation_window_days
#> [1] 14
#> 
#> 
#> $therapy_obs_window_without
#> $therapy_obs_window_without$therapy_days
#> [1] 7
#> 
#> $therapy_obs_window_without$observation_window_days
#> [1] 14
#> 
#> 
#> $medications
#>    medication_name dose doses_per_24_hours days_of_medication factor mme
#> 1 Hydrocodone (mg)   10                  4                  7    1.0 280
#> 2   Oxycodone (mg)    5                  2                  5    1.5  75
#>   single_day_mme
#> 1             40
#> 2             15
#> 
#> $mme_definitions
#> $mme_definitions$with_buprenorphine
#>   total_mme total_days     mme1     mme2     mme3 mme4
#> 1       355         12 29.58333 50.71429 25.35714   55
#> 
#> $mme_definitions$without_buprenorphine
#>   total_mme total_days     mme1     mme2     mme3 mme4
#> 1       355         12 29.58333 50.71429 25.35714   55

The inputs and outputs are identical to calculate_mme() with use_api = TRUE (the default), but no external API calls are made.

Working with data.frames and tibbles

For real-world data analysis, you’ll often have medication data in a data.frame or tibble rather than a list. As an example, mmequiv contains a synthetic dataset called opioid_trial that contains one row per opioid prescription for 1000 fake patients (long format) with each row containing the variables required for MME calculation. For large datasets that would take an annoyingly long time to calculate using the API (recall the API rate limit of 50 patients per 15 minutes), we can use calculate_mme.data.frame():

# View the example dataset structure
head(opioid_trial)
#>   patient_id         medication_name  dose doses_per_24_hours
#> 1       P001 Fentanyl patch (mcg/hr)  12.5                  1
#> 2       P001        tramadol (mg) LA 125.0                  1
#> 3       P002        Hydrocodone (mg)  10.0                  3
#> 4       P002           tramadol (mg)  60.0                  3
#> 5       P003     Meperidine HCL (mg)  50.0                  4
#> 6       P003           tramadol (mg)  90.0                  3
#>   days_of_medication therapy_days observation_window_days therapy_days_without
#> 1                  7            7                      30                    7
#> 2                 30           30                      45                   30
#> 3                 14           14                      30                   14
#> 4                 14           14                      30                   14
#> 5                  7            7                      30                    7
#> 6                  7            7                      30                    7
#>   observation_window_days_without
#> 1                              30
#> 2                              45
#> 3                              30
#> 4                              30
#> 5                              30
#> 6                              30

# Calculate MME from a data frame
mme_df_result <- calculate_mme(
  x = opioid_trial,
  therapy_days_without_col = "therapy_days_without",
  observation_days_without_col = "observation_window_days_without"
)

calculate_mme() uses S3 methods and will automatically select the underlying actions needed based on the class of x. calculate_mme.data.frame() has several arguments not shown in the example above that deal with specifying column names if supplying column names that differ from the function’s defaults.

The results from calculate_mme.data.frame() include:

# Original data with MME calculations added
head(mme_df_result$medications)
#>   patient_id         medication_name  dose doses_per_24_hours
#> 1       P001 Fentanyl patch (mcg/hr)  12.5                  1
#> 2       P001        tramadol (mg) LA 125.0                  1
#> 3       P002        Hydrocodone (mg)  10.0                  3
#> 4       P002           tramadol (mg)  60.0                  3
#> 5       P003     Meperidine HCL (mg)  50.0                  4
#> 6       P003           tramadol (mg)  90.0                  3
#>   days_of_medication therapy_days observation_window_days therapy_days_without
#> 1                  7            7                      30                    7
#> 2                 30           30                      45                   30
#> 3                 14           14                      30                   14
#> 4                 14           14                      30                   14
#> 5                  7            7                      30                    7
#> 6                  7            7                      30                    7
#>   observation_window_days_without factor mme single_day_mme
#> 1                              30    2.4 210             30
#> 2                              45    0.2 750             25
#> 3                              30    1.0 420             30
#> 4                              30    0.2 504             36
#> 5                              30    0.1 140             20
#> 6                              30    0.2 378             54

# Patient-level summaries with buprenorphine
head(mme_df_result$patient_summary_with_buprenorphine)
#>   patient_id therapy_days observation_window_days total_mme total_days
#> 1       P001            7                      30    960.00         37
#> 2       P002           14                      30    924.00         28
#> 3       P003            7                      30   2228.00         31
#> 4       P004            7                      30    210.00          7
#> 5       P005            7                      30     47.25          7
#> 6       P006            7                      30   3395.25         31
#>        mme1     mme2      mme3   mme4
#> 1  25.94595 137.1429  32.00000  55.00
#> 2  33.00000  66.0000  30.80000  66.00
#> 3  71.87097 318.2857  74.26667 204.00
#> 4  30.00000  30.0000   7.00000  30.00
#> 5   6.75000   6.7500   1.57500   6.75
#> 6 109.52419 485.0357 113.17500 393.75

# Patient-level summaries without buprenorphine
head(mme_df_result$patient_summary_without_buprenorphine)
#>   patient_id therapy_days observation_window_days total_mme total_days
#> 1       P001            7                      30    960.00         37
#> 2       P002           14                      30    924.00         28
#> 3       P003            7                      30   2228.00         31
#> 4       P004            7                      30    210.00          7
#> 5       P005            7                      30     47.25          7
#> 6       P006            7                      30   3395.25         31
#>        mme1     mme2      mme3   mme4
#> 1  25.94595 137.1429  32.00000  55.00
#> 2  33.00000  66.0000  30.80000  66.00
#> 3  71.87097 318.2857  74.26667 204.00
#> 4  30.00000  30.0000   7.00000  30.00
#> 5   6.75000   6.7500   1.57500   6.75
#> 6 109.52419 485.0357 113.17500 393.75

Choosing the Right MME Definition

The package calculates four different MME/day definitions, each suited for different research questions:

  1. MME Definition 1 (mme1): Total MME divided by Total Days Supply

    • Best suited for studies of immediate-release opioids prescribed for short, discrete periods
  2. MME Definition 2 (mme2): Total MME divided by On-therapy Days

    • Ideal for studies of dose-dependent adverse effects (e.g., opioid-induced constipation)

    • Useful for patients with opioid tolerance or stable on opioids

  3. MME Definition 3 (mme3): Total MME divided by Fixed Observation Window

    • Recommended by the Department of Health and Human Services Office of the Inspector General
    • Suitable for studies with a known duration of risk (e.g., opioid use disorder incidence)
    • Useful when prescriptions are filled at irregular intervals (PRN basis)
  4. MME Definition 4 (mme4): Maximum Daily Dose

    • Appropriate for patients with no opioid tolerance or with comorbidities for respiratory depression
    • Used in the CDC Opioid Guideline mobile app
    • Best for immediate dose-dependent toxic effects (e.g., respiratory depression)

Choose the definition that best aligns with your research question and population.

Important Caveats

Remember that mmequiv, like the NIH HEAL MME Online Calculator, is only intended for:

  • Research
  • Analytical purposes using claims or dispensing data
  • Surveillance of population-level medication utilization

The calculations are not intended for:

  • Clinical decision-making while prescribing opioids
  • Clinical guidance for prescribing
  • Recommendations for converting patients from one opioid analgesic to another

Conclusion

mmequiv provides a comprehensive set of tools for calculating standardized MME in research settings. Whether you’re working with small samples through the calling the NIH HEAL MME Online Calculator API or large datasets with local calculations, the package offers consistent, validated methods to support your research.

For more information on the methodology behind these calculations, refer to Adams, et al. (2025).