Skip to contents

[Experimental]

Converts CDISC timepoint strings (e.g., PCTPT, VSTPT, EGTPT, ISTPT, LBTPT) into numeric hours for analysis. The function handles common dose-centric formats including pre-dose, post-dose (hours/minutes), days, time ranges, and treatment-related time markers.

Usage

convert_xxtpt_to_hours(
  xxtpt,
  treatment_duration = 0,
  range_method = "midpoint"
)

Arguments

xxtpt

A character vector of timepoint descriptions from SDTM --TPT variables (e.g., PCTPT, VSTPT, EGTPT, ISTPT, LBTPT). Can contain NA values.

Permitted values

character vector

Default value

none

treatment_duration

Numeric value(s) specifying the duration of treatment in hours. Used to convert "EOI/EOT" (End of Infusion/Treatment) patterns and patterns describing time after end of treatment. Must be non-negative. Can be either:

  • A single value (used for all timepoints), or

  • A vector of the same length as xxtpt (one value per timepoint)

Default is 0 hours (for instantaneous treatments like oral medications).

Permitted values

numeric scalar or vector (non-negative)

Default value

0

range_method

Method for converting time ranges to single values. Options are "midpoint" (default), "start", or "end". For example, "0-6h" with midpoint returns 3, with start returns 0, with end returns 6.

Permitted values

character scalar ("midpoint", "start", or "end")

Default value

"midpoint"

Value

A numeric vector of timepoints in hours. Returns NA_real_ for:

  • Input NA values

  • Unrecognized timepoint formats

  • Non-time descriptors (e.g., "Morning", "Evening")

Returns numeric(0) for empty input.

Details

The function recognizes the following patterns (all case-insensitive):

Special Cases:

  • "Screening" -> 0

  • "Pre-dose", "Predose", "Pre-treatment", "Pre-infusion", "Pre-inf", "Before", "Infusion", "0H" -> 0

  • "EOI", "EOT", "End of Infusion", "End of Treatment", "After End of Infusion", "After End of Treatment" -> treatment_duration (default: 0)

  • "Morning", "Evening" -> NA_real_

  • Unrecognized values -> NA_real_

Time Ranges: Time ranges are converted based on the range_method parameter:

  • "0-6h Post-dose" with range_method = "midpoint" (default) -> 3

  • "0-6h Post-dose" with range_method = "start" -> 0

  • "0-6h Post-dose" with range_method = "end" -> 6

  • "0-4H PRIOR START OF INFUSION" with midpoint -> -2 (negative for prior)

  • "8-16H POST START OF INFUSION" with midpoint -> 12

  • "0-4H AFTER EOI" with midpoint and treatment_duration=1 -> 3 (1 + 2)

  • "0-4H EOT" with midpoint and treatment_duration=0 -> 2

  • "4-8H AFTER END OF INFUSION" with midpoint and treatment_duration=1 -> 7 (1 + 6)

  • "4-8H POST INFUSION" with midpoint and treatment_duration=1 -> 7 (1 + 6)

  • "4-8H POST-INF" with midpoint and treatment_duration=1 -> 7 (1 + 6)

Time-based Conversions:

  • Days: "Day 1" -> 24, "2D" -> 48, "30 DAYS AFTER LAST" -> 720 (requires unit indicator; bare numbers like "2" return NA)

  • Hours + Minutes: "1H30M" -> 1.5

  • Hours: "2 hours" -> 2, "1 HOUR POST" -> 1

  • Minutes: "30M" -> 0.5, "30 MIN POST" -> 0.5

  • Predose: "5 MIN PREDOSE" -> -0.0833, "5 MIN PRE-DOSE" -> -0.0833

  • Before treatment: "5 MIN BEFORE" -> -0.0833

  • Post EOI/EOT: "1 HOUR POST EOI" -> treatment_duration + 1, "24 HR POST INF" -> treatment_duration + 24, "24 HR POST-INF" -> treatment_duration + 24, "1 HOUR AFTER EOT" -> treatment_duration + 1

  • After end: "30MIN AFTER END OF INFUSION" -> treatment_duration + 0.5

  • Start of infusion/treatment: "8H PRIOR START OF INFUSION" -> -8, "8H BEFORE START OF TREATMENT" -> -8

  • Pre EOI/EOT: "10MIN PRE EOI" -> treatment_duration - 1/6, "10MIN BEFORE EOT" -> treatment_duration - 1/6

Supported Unit Formats:

  • Hours: H, h, HR, hr, HOUR, hour (with optional plurals)

  • Minutes: M, m, MIN, min, MINUTE, minute (with optional plurals)

  • Days: D, d, DAY, day (with optional plurals)

  • Flexible whitespace and optional "Post-dose", "POST", "After last" suffixes

  • Hyphens in compound terms: "PRE-DOSE", "POST-INF", "POST-INFUSION"

Understanding POST/AFTER Patterns:

It's important to distinguish between patterns relative to treatment start versus treatment end:

  • Relative to START (treatment_duration NOT added):

    • "1H POST", "1H AFTER", "30M POST" -> Time from dose/treatment start

    • These patterns assume treatment starts at time 0

    • Example: "1H POST" -> 1 hour (regardless of treatment_duration)

  • Relative to END (treatment_duration IS added):

    • "1H POST EOI", "1H AFTER EOT", "1H POST INFUSION" -> Time from treatment end

    • These patterns account for when treatment ends (start + duration)

    • Example: "1H POST EOI" with treatment_duration=2 -> 3 hours (2 + 1)

This distinction follows standard pharmacokinetic conventions where "post-dose" refers to time from treatment initiation, while "post end of infusion" refers to time from treatment completion.

Vectorized Treatment Duration:

When treatment_duration is a vector, each timepoint uses its corresponding treatment duration value. This is useful when different records have different treatment durations (e.g., different infusion lengths).

See also

Examples

Basic timepoint patterns

Convert basic dose-centric patterns to hours

convert_xxtpt_to_hours(c(
  "Screening",
  "Pre-dose",
  "Pre-treatment",
  "Before",
  "30M",
  "1H",
  "2H POSTDOSE",
  "Day 1"
))
#> [1]  0.0  0.0  0.0  0.0  0.5  1.0  2.0 24.0

Predose and before patterns

Convert predose/before patterns that return negative times

convert_xxtpt_to_hours(c("5 MIN PREDOSE", "5 MIN PRE-DOSE", "1 HOUR BEFORE"))
#> [1] -0.08333333 -0.08333333 -1.00000000

With default treatment_duration = 0 for oral medications

convert_xxtpt_to_hours(c(
  "EOT",
  "1 HOUR POST EOT",
  "1 HOUR AFTER EOT",
  "After End of Treatment"
))
#> [1] 0 1 1 0

With treatment_duration = 1 hour for IV infusions

convert_xxtpt_to_hours(
  c(
    "EOI",
    "1 HOUR POST EOI",
    "24 HR POST INF",
    "24 HR POST-INF",
    "30MIN AFTER END OF INFUSION",
    "8H PRIOR START OF INFUSION",
    "10MIN PRE EOI"
  ),
  treatment_duration = 1
)
#> [1]  1.0000000  2.0000000 25.0000000 25.0000000  1.5000000 -8.0000000  0.8333333

Vectorized treatment duration

Different treatment durations per timepoint

convert_xxtpt_to_hours(
  c("EOI", "1 HOUR POST EOI", "EOI", "1 HOUR POST EOI"),
  treatment_duration = c(1, 1, 2, 2)
)
#> [1] 1 2 2 3

Time ranges with midpoint method

Default midpoint method for ranges

convert_xxtpt_to_hours(c(
  "0-6h Post-dose",
  "0-4H PRIOR START OF INFUSION",
  "8-16H POST START OF INFUSION"
))
#> [1]  3 -2 12

Time ranges with custom methods

Specify start or end method for ranges

convert_xxtpt_to_hours("0-6h Post-dose", range_method = "end")
#> [1] 6
convert_xxtpt_to_hours("0-6h Post-dose", range_method = "start")
#> [1] 0

Ranges relative to EOI/EOT

Time ranges after end of infusion/treatment

convert_xxtpt_to_hours(
  c(
    "0-4H AFTER EOI",
    "0-4H POST EOI",
    "4-8H AFTER END OF INFUSION",
    "4-8H AFTER EOT",
    "4-8H POST INFUSION",
    "4-8H POST-INF"
  ),
  treatment_duration = 1
)
#> [1] 3 3 7 7 7 7

POST vs POST EOI distinction

Difference between POST (from start) and POST EOI (from end)

convert_xxtpt_to_hours(
  c("Pre-dose", "1H POST", "2H POST", "4H POST"),
  treatment_duration = 2
)
#> [1] 0 1 2 4

convert_xxtpt_to_hours(
  c("Pre-dose", "EOI", "1H POST EOI", "2H POST EOI"),
  treatment_duration = 2
)
#> [1] 0 2 3 4

convert_xxtpt_to_hours(
  c("1H POST", "1H POST EOI", "1H POST INFUSION"),
  treatment_duration = 2
)
#> [1] 1 3 3