Creating an Events SDTM domain

Introduction

This article describes creating an Events SDTM domain using the sdtm.oak package. Examples are currently presented and tested in the context of the CM domain.

Raw data

Raw datasets can be exported from the EDC systems in the format they are collected. The example used provides a raw dataset for Concomitant medications, where the collected data is represented as columns for each subject. For example, the Medication Name(MDRAW), Medication Start Date (MDBDR), Start Time (MDBTM), End Date (MDEDR), End time (MDETM), etc. are represented as columns.This format is commonly used in most EDC systems.

The raw dataset is presented below:

PATNUM FORML MDNUM MDRAW MDIND MDBDR MDBTM MDPRIOR MDEDR MDETM MDONG DOS DOSU MDFORM MDRTE MDFRQ MDPROPH
375 Concomitant Medications 1 BABY ASPIRIN 1 1 10 mg Tablet PO (Oral) QD (Every Day) 0
375 Concomitant Medications 2 CORTISPORIN NAUSEA 15-Sep-20 0 1 50 g Pill PO (Oral) 0
376 Concomitant Medications 1 ASPIRIN ANEMIA 17-Feb-21 8:00 0 17-Feb-21 0 NA 0
377 Concomitant Medications 1 DIPHENHYDRAMINE HCL NAUSEA 4-Oct-20 9:00 0 1 50 mg Capsule PO (Oral) BID (Twice a Day) 0
377 Concomitant Medications 2 PARCETEMOL PYREXIA 20-Jan-20 10:00 0 20-Jan-20 10:00 0 NA mg Capsule PO (Oral) BID (Twice a Day) 1
377 Concomitant Medications 3 VOMIKIND VOMITINGS UN UNK 2019 0 UN UNK 2019 0 NA Tablet PO (Oral) PRN (As Needed) 1
377 Concomitant Medications 5 ZENFLOX OZ DIARHHEA 20 UNK 2019 10:00 0 20 UNK 2019 0 NA mL Injection IM (Intramuscular) PRN (As Needed) 1
378 Concomitant Medications 4 AMITRYPTYLINE COLD UN UNK 2020 1 UN UNK 2020 0 12 g Inhalant IA (Intra-arterial) QD (Every Day) 0
378 Concomitant Medications 1 BENADRYL FEVER 26-Jan-20 9:00 0 26-Jan-20 7:00 0 100 mg Capsule PO (Oral) BID (Twice a Day) 1
378 Concomitant Medications 2 DIPHENHYDRAMINE HYDROCHLORIDE LEG PAIN 28-Jan-20 1 1-Feb-20 1 100 Capsule Capsule Unknown QD (Every Day) 0

Programming workflow

In {sdtm.oak} we process one raw dataset at a time. Similar raw datasets (example Concomitant medications (OID - cm_raw), Targeted Concomitant Medications (OID - cm_t_raw)) can be stacked together before processing.

Repeat the above steps for different raw datasets before proceeding with the below steps.

Read in data

Read all the raw datasets into the environment. In this example, the raw dataset name is cm_raw. Users can read it from the package using the below code:

cm_raw <- read.csv(system.file("raw_data/cm_raw_data.csv",
  package = "sdtm.oak"
))

Create oak_id_vars

The oak_id_vars is a crucial link between the raw datasets and the mapped SDTM domain. As the user derives each SDTM variable, it is merged with the corresponding topic variable using oak_id_vars. In {sdtm.oak}, the variables oak_id, raw_source, and patient_number are considered as oak_id_vars. These three variables must be added to all raw datasets. They are used in multiple places in the programming.

oak_id:- Type: numeric- Value: equal to the raw dataframe row number.

raw_source:- Type: Character- Value: equal to the raw dataset (eCRF) name or eDT dataset name.

patient_number:- Type: numeric- Value: equal to the subject number in CRF or NonCRF data source.

cm_raw <- cm_raw %>%
  generate_oak_id_vars(
    pat_var = "PATNUM",
    raw_src = "cm_raw"
  )
oak_id raw_source patient_number PATNUM FORML MDNUM MDRAW
1 cm_raw 375 375 Concomitant Medications 1 BABY ASPIRIN
2 cm_raw 375 375 Concomitant Medications 2 CORTISPORIN
3 cm_raw 376 376 Concomitant Medications 1 ASPIRIN
4 cm_raw 377 377 Concomitant Medications 1 DIPHENHYDRAMINE HCL
5 cm_raw 377 377 Concomitant Medications 2 PARCETEMOL
6 cm_raw 377 377 Concomitant Medications 3 VOMIKIND
7 cm_raw 377 377 Concomitant Medications 5 ZENFLOX OZ
8 cm_raw 378 378 Concomitant Medications 4 AMITRYPTYLINE
9 cm_raw 378 378 Concomitant Medications 1 BENADRYL
10 cm_raw 378 378 Concomitant Medications 2 DIPHENHYDRAMINE HYDROCHLORIDE

Read in the DM domain

dm <- read.csv(system.file("raw_data/dm.csv",
  package = "sdtm.oak"
))

Read in CT

Controlled Terminology is part of the SDTM specification and it is prepared by the user. In this example, the study controlled terminology name is sdtm_ct.csv. Users can read it from the package using the below code:

study_ct <- read.csv(system.file("raw_data/sdtm_ct.csv",
  package = "sdtm.oak"
))
codelist_code term_code term_value collected_value term_preferred_term term_synonyms
C66726 C25158 CAPSULE Capsule Capsule Dosage Form cap
C66726 C25394 PILL Pill Pill Dosage Form
C66726 C29167 LOTION Lotion Lotion Dosage Form
C66726 C42887 AEROSOL Aerosol Aerosol Dosage Form aer
C66726 C42944 INHALANT Inhalant Inhalant Dosage Form
C66726 C42946 INJECTION Injection Injectable Dosage Form
C66726 C42953 LIQUID Liquid Liquid Dosage Form
C66726 C42998 TABLET Tablet Tablet Dosage Form tab
C66728 C25629 BEFORE Prior Prior
C66728 C53279 ONGOING Continue Continue Continuous

Map Topic Variable

The topic variable is mapped as a first step in the mapping process. It is the primary variable in the SDTM domain. The rest of the variables add further definition to the topic variable. In this example, the topic variable is CMTRT. It is mapped from the raw dataset column MDRAW. The mapping logic is Map the collected value in the cm_raw dataset MDRAW variable to CM.CMTRT.

This mapping does not involve any controlled terminology. The assign_no_ct function is used for mapping. Once the topic variable is mapped, the Qualifier, Identifier, and Timing variables can be mapped.

cm <-
  # Map topic variable
  assign_no_ct(
    raw_dat = cm_raw,
    raw_var = "MDRAW",
    tgt_var = "CMTRT"
  )
oak_id raw_source patient_number CMTRT
1 cm_raw 375 BABY ASPIRIN
2 cm_raw 375 CORTISPORIN
3 cm_raw 376 ASPIRIN
4 cm_raw 377 DIPHENHYDRAMINE HCL
5 cm_raw 377 PARCETEMOL
6 cm_raw 377 VOMIKIND
7 cm_raw 377 ZENFLOX OZ
8 cm_raw 378 AMITRYPTYLINE
9 cm_raw 378 BENADRYL
10 cm_raw 378 DIPHENHYDRAMINE HYDROCHLORIDE

Map Rest of the Variables

The Qualifiers, Identifiers, and Timing Variables can be mapped in any order. In this example, we will map each variable one by one to demonstrate different mapping algorithms.

assign_no_ct

The mapping logic for CMGRPID is Map the collected value in the cm_raw dataset MDNUM variable to CM.CMGRPID.

cm <- cm %>%
  # Map CMGRPID
  assign_no_ct(
    raw_dat = cm_raw,
    raw_var = "MDNUM",
    tgt_var = "CMGRPID",
    id_vars = oak_id_vars()
  )
oak_id raw_source patient_number CMTRT CMGRPID
1 cm_raw 375 BABY ASPIRIN 1
2 cm_raw 375 CORTISPORIN 2
3 cm_raw 376 ASPIRIN 1
4 cm_raw 377 DIPHENHYDRAMINE HCL 1
5 cm_raw 377 PARCETEMOL 2
6 cm_raw 377 VOMIKIND 3
7 cm_raw 377 ZENFLOX OZ 5
8 cm_raw 378 AMITRYPTYLINE 4
9 cm_raw 378 BENADRYL 1
10 cm_raw 378 DIPHENHYDRAMINE HYDROCHLORIDE 2

The CMGRPID is added to the corresponding CMTRT based on the ‘oak_id_vars’. When calling the function, the parameter ‘id_vars = oak_id_vars()’ matches the raw dataset ‘oak_id_vars’ to the ‘oak_id_vars’ in the cm domain created in the previous step. It’s important to note that the ‘oak_id_vars’ can be extended to include user-defined variables. But in most cases, the three variables should suffice.

assign_ct

The mapping logic for CMDOSU is Map the collected value in the cm_raw dataset DOSU variable to CM.CMDOSU. The controlled terminology is used to map the collected value to the standard value. assign_ct is the right algorithm to perform this mapping.

cm <- cm %>%
  # Map qualifier CMDOSU
  assign_ct(
    raw_dat = cm_raw,
    raw_var = "DOSU",
    tgt_var = "CMDOSU",
    ct_spec = study_ct,
    ct_clst = "C71620",
    id_vars = oak_id_vars()
  )
oak_id raw_source patient_number CMTRT CMGRPID CMDOSU
1 cm_raw 375 BABY ASPIRIN 1 mg
2 cm_raw 375 CORTISPORIN 2 g
3 cm_raw 376 ASPIRIN 1
4 cm_raw 377 DIPHENHYDRAMINE HCL 1 mg
5 cm_raw 377 PARCETEMOL 2 mg
6 cm_raw 377 VOMIKIND 3 TABLET
7 cm_raw 377 ZENFLOX OZ 5 mL
8 cm_raw 378 AMITRYPTYLINE 4 g
9 cm_raw 378 BENADRYL 1 mg
10 cm_raw 378 DIPHENHYDRAMINE HYDROCHLORIDE 2 CAPSULE

assign_datetime

The mapping logic for CMSTDTC is Map the collected value in the cm_raw dataset MDBDR (start date) variable and MDBTM (start time) to CM.CMSTDTC. The collected date value is in the format ‘dd mmm yyyy’. The collected time value is in ‘H”M’ format. The assign_datetime function is used to map the collected value in ISO8601 format.

cm <- cm %>%
  # Map CMSTDTC. This function calls create_iso8601
  assign_datetime(
    raw_dat = cm_raw,
    raw_var = c("MDBDR", "MDBTM"),
    tgt_var = "CMSTDTC",
    raw_fmt = c(list(c("d-m-y", "dd mmm yyyy")), "H:M"),
    raw_unk = c("UN", "UNK"),
    id_vars = oak_id_vars()
  )
oak_id raw_source patient_number CMTRT CMGRPID CMDOSU CMSTDTC
1 cm_raw 375 BABY ASPIRIN 1 mg NA
2 cm_raw 375 CORTISPORIN 2 g 2020-09-15
3 cm_raw 376 ASPIRIN 1 2021-02-17T08:00
4 cm_raw 377 DIPHENHYDRAMINE HCL 1 mg 2020-10-04T09:00
5 cm_raw 377 PARCETEMOL 2 mg 2020-01-20T10:00
6 cm_raw 377 VOMIKIND 3 TABLET 2019
7 cm_raw 377 ZENFLOX OZ 5 mL 2019—20T10:00
8 cm_raw 378 AMITRYPTYLINE 4 g 2020
9 cm_raw 378 BENADRYL 1 mg 2020-01-26T09:00
10 cm_raw 378 DIPHENHYDRAMINE HYDROCHLORIDE 2 CAPSULE 2020-01-28

hardcode_ct and condition_add

The mapping logic for CMSTRTPT is as follows: If the collected value in the raw variable MDPRIOR and raw dataset cm_raw equals to 1, then CM.CMSTRTPT == 'BEFORE'. The hardcode_ct function is used to map the CMSTRTPT as it involves hardcoding a specific value to an SDTM variable with controlled terminology. The condition_add function filters the raw dataset based on a particular condition, and the hardcode_ct function performs the mapping.

When these two functions are used together, the condition_add function first filters the raw dataset based on the specified condition. Next, the filtered dataset is then passed to the hardcode_ct function to assign the appropriate value. This example illustrates how the hardcode_ct algorithm functions as a sub-algorithm to condition_add.

cm <- cm %>%
  # Map qualifier CMSTRTPT  Annotation text is If MDPRIOR == 1 then CM.CMSTRTPT = 'BEFORE'
  hardcode_ct(
    raw_dat = condition_add(cm_raw, MDPRIOR == "1"),
    raw_var = "MDPRIOR",
    tgt_var = "CMSTRTPT",
    tgt_val = "BEFORE",
    ct_spec = study_ct,
    ct_clst = "C66728",
    id_vars = oak_id_vars()
  )
oak_id raw_source patient_number CMTRT CMGRPID CMDOSU CMSTDTC CMSTRTPT
1 cm_raw 375 BABY ASPIRIN 1 mg NA BEFORE
2 cm_raw 375 CORTISPORIN 2 g 2020-09-15 NA
3 cm_raw 376 ASPIRIN 1 2021-02-17T08:00 NA
4 cm_raw 377 DIPHENHYDRAMINE HCL 1 mg 2020-10-04T09:00 NA
5 cm_raw 377 PARCETEMOL 2 mg 2020-01-20T10:00 NA
6 cm_raw 377 VOMIKIND 3 TABLET 2019 NA
7 cm_raw 377 ZENFLOX OZ 5 mL 2019—20T10:00 NA
8 cm_raw 378 AMITRYPTYLINE 4 g 2020 BEFORE
9 cm_raw 378 BENADRYL 1 mg 2020-01-26T09:00 NA
10 cm_raw 378 DIPHENHYDRAMINE HYDROCHLORIDE 2 CAPSULE 2020-01-28 BEFORE

The condition_add function adds additional metadata to the records in the raw dataset that meets the condition. Refer to the function documentation for more details. hardcode_ct function uses the additional metadata to find the records that meet the criteria and map them accordingly.

hardcode_no_ct and condition_add

The mapping logic for CMSTTPT is as follows: If the collected value in the raw variable MDPRIOR and raw dataset cm_raw equals to 1, then CM.CMSTTPT == 'SCREENING'. The hardcode_no_ct function is used to map the CMSTTPT as it involves hardcoding a specific value to an SDTM variable without controlled terminology. The condition_add function filters the raw dataset based on a particular condition, and the hardcode_no_ct function performs the mapping.

cm <- cm %>%
  # Map qualifier CMSTTPT  Annotation text is If MDPRIOR == 1 then CM.CMSTTPT = 'SCREENING'
  hardcode_no_ct(
    raw_dat = condition_add(cm_raw, MDPRIOR == "1"),
    raw_var = "MDPRIOR",
    tgt_var = "CMSTTPT",
    tgt_val = "SCREENING",
    id_vars = oak_id_vars()
  )
oak_id raw_source patient_number CMTRT CMGRPID CMDOSU CMSTDTC CMSTRTPT CMSTTPT
1 cm_raw 375 BABY ASPIRIN 1 mg NA BEFORE SCREENING
2 cm_raw 375 CORTISPORIN 2 g 2020-09-15 NA NA
3 cm_raw 376 ASPIRIN 1 2021-02-17T08:00 NA NA
4 cm_raw 377 DIPHENHYDRAMINE HCL 1 mg 2020-10-04T09:00 NA NA
5 cm_raw 377 PARCETEMOL 2 mg 2020-01-20T10:00 NA NA
6 cm_raw 377 VOMIKIND 3 TABLET 2019 NA NA
7 cm_raw 377 ZENFLOX OZ 5 mL 2019—20T10:00 NA NA
8 cm_raw 378 AMITRYPTYLINE 4 g 2020 BEFORE SCREENING
9 cm_raw 378 BENADRYL 1 mg 2020-01-26T09:00 NA NA
10 cm_raw 378 DIPHENHYDRAMINE HYDROCHLORIDE 2 CAPSULE 2020-01-28 BEFORE SCREENING

condition_add involving target domain

In the mapping for CMSTRTPT and CMSTTTPT, the condition_add function is used in the raw dataset. In this mapping, we can explore how to use condition_add to add a filter condition based on the target SDTM variable.

The mapping logic for CMDOSFRQ is If CMTRT is not null, then map the collected value in raw dataset cm_raw and raw variable MDFRQ to CMDOSFRQ. This may or may not represent a valid SDTM mapping in an actual study, but it can be used as an example.

In this mapping, the condition_add function filters the cm domain created in the previous step and adds metadata to the records where it meets the condition. The assign_ct function uses the additional metadata to find the records that meet the criteria and map them accordingly.

cm <- cm %>%
  # Map qualifier CMDOSFRQ  Annotation text is If CMTRT is not null then map
  # the collected value in raw dataset cm_raw and raw variable MDFRQ to CMDOSFRQ
  {
    assign_ct(
      raw_dat = cm_raw,
      raw_var = "MDFRQ",
      tgt_dat =  condition_add(., !is.na(CMTRT)),
      tgt_var = "CMDOSFRQ",
      ct_spec = study_ct,
      ct_clst = "C66728",
      id_vars = oak_id_vars()
    )
  }
oak_id raw_source patient_number CMTRT CMGRPID CMDOSU CMSTDTC CMSTRTPT CMSTTPT CMDOSFRQ
1 cm_raw 375 BABY ASPIRIN 1 mg NA BEFORE SCREENING QD (EVERY DAY)
2 cm_raw 375 CORTISPORIN 2 g 2020-09-15 NA NA
3 cm_raw 376 ASPIRIN 1 2021-02-17T08:00 NA NA
4 cm_raw 377 DIPHENHYDRAMINE HCL 1 mg 2020-10-04T09:00 NA NA BID (TWICE A DAY)
5 cm_raw 377 PARCETEMOL 2 mg 2020-01-20T10:00 NA NA BID (TWICE A DAY)
6 cm_raw 377 VOMIKIND 3 TABLET 2019 NA NA PRN (AS NEEDED)
7 cm_raw 377 ZENFLOX OZ 5 mL 2019—20T10:00 NA NA PRN (AS NEEDED)
8 cm_raw 378 AMITRYPTYLINE 4 g 2020 BEFORE SCREENING QD (EVERY DAY)
9 cm_raw 378 BENADRYL 1 mg 2020-01-26T09:00 NA NA BID (TWICE A DAY)
10 cm_raw 378 DIPHENHYDRAMINE HYDROCHLORIDE 2 CAPSULE 2020-01-28 BEFORE SCREENING QD (EVERY DAY)

Remember to use additional curly braces in the function call when using the condition_add function on the target dataset. This is necessary because the input target dataset is represented as a . and is passed on from the previous step using the {magrittr} pipe operator. Currently, there is a limitation when using a nested function call with . to reference one of the input parameters, and this recommended approach will overcome that.

The placeholder . is for use with {magrittr} pipe %>% operator. We encourage using . and {magrittr} pipe %>% operator when using {sdtm.oak} functions.

Another way to achieve the same outcome is by moving the ‘condition_by’ call up one level, as illustrated below: it is not required to use the {magrittr} pipe %>% or curly braces in this case.

cm <- cm %>%
  condition_add(!is.na(CMTRT)) %>%
  assign_ct(
    raw_dat = cm_raw,
    raw_var = "DOSU",
    tgt_var = "CMDOSU",
    ct_spec = study_ct,
    ct_clst = "C71620",
    id_vars = oak_id_vars()
  )

condition_add involving raw dataset and target domain

In this mapping, we can explore how to use condition_add to add a filter condition based on the target SDTM variable.

The mapping logic for CMMODIFY is If collected value in MODIFY in cm_raw is different to CM.CMTRT then assign the collected value to CMMODIFY in CM domain (CM.CMMODIFY). The assign_no_ct function is used to map the CMMODIFY as it involves mapping the collected value to the SDTM variable without controlled terminology. The condition_add function filters the raw dataset & target dataset based on a particular condition, and the assign_no_ct function performs the mapping.

cm <- cm %>%
  # Map CMMODIFY  Annotation text  If collected value in MODIFY in cm_raw is
  # different to CM.CMTRT then assign the collected value to CMMODIFY in
  # CM domain (CM.CMMODIFY)
  {
    assign_no_ct(
      raw_dat = cm_raw,
      raw_var = "MODIFY",
      tgt_dat = condition_add(., MODIFY != CMTRT, .dat2 = cm_raw),
      tgt_var = "CMMODIFY",
      id_vars = oak_id_vars()
    )
  }
oak_id raw_source patient_number CMTRT CMGRPID CMDOSU CMSTDTC CMSTRTPT CMSTTPT CMDOSFRQ CMMODIFY
1 cm_raw 375 BABY ASPIRIN 1 mg NA BEFORE SCREENING QD (EVERY DAY) NA
2 cm_raw 375 CORTISPORIN 2 g 2020-09-15 NA NA CORTISPORIN (UNITED STATES)
3 cm_raw 376 ASPIRIN 1 2021-02-17T08:00 NA NA NA
4 cm_raw 377 DIPHENHYDRAMINE HCL 1 mg 2020-10-04T09:00 NA NA BID (TWICE A DAY) NA
5 cm_raw 377 PARCETEMOL 2 mg 2020-01-20T10:00 NA NA BID (TWICE A DAY)
6 cm_raw 377 VOMIKIND 3 TABLET 2019 NA NA PRN (AS NEEDED)
7 cm_raw 377 ZENFLOX OZ 5 mL 2019—20T10:00 NA NA PRN (AS NEEDED)
8 cm_raw 378 AMITRYPTYLINE 4 g 2020 BEFORE SCREENING QD (EVERY DAY) AMITRIPTYLINE
9 cm_raw 378 BENADRYL 1 mg 2020-01-26T09:00 NA NA BID (TWICE A DAY) BENADRYL (UNITED STATES)
10 cm_raw 378 DIPHENHYDRAMINE HYDROCHLORIDE 2 CAPSULE 2020-01-28 BEFORE SCREENING QD (EVERY DAY) NA

Another way to achieve the same outcome is by moving the ‘condition_by’ call up one level, as illustrated below: it is not required to use the {magrittr} pipe %>% or curly braces in this case.

cm <- cm %>%
  condition_add(MODIFY != CMTRT, .dat2 = cm_raw) %>%
  assign_no_ct(
    raw_dat = cm_raw,
    raw_var = "MODIFY",
    tgt_var = "CMMODIFY",
    id_vars = oak_id_vars()
  )

Now, complete mapping the rest of the SDTM variables.

cm <- cm %>%
  # Map CMINDC as the collected value in MDIND to CM.CMINDC
  assign_no_ct(
    raw_dat = cm_raw,
    raw_var = "MDIND",
    tgt_var = "CMINDC",
    id_vars = oak_id_vars()
  ) %>%
  # Map CMENDTC as the collected value in MDEDR and MDETM to CM.CMENDTC.
  # This function calls create_iso8601
  assign_datetime(
    raw_dat = cm_raw,
    raw_var = c("MDEDR", "MDETM"),
    tgt_var = "CMENDTC",
    raw_fmt = c("d-m-y", "H:M"),
    raw_unk = c("UN", "UNK")
  ) %>%
  # Map qualifier CMENRTPT as If MDONG == 1 then CM.CMENRTPT = 'ONGOING'
  hardcode_ct(
    raw_dat = condition_add(cm_raw, MDONG == "1"),
    raw_var = "MDONG",
    tgt_var = "CMENRTPT",
    tgt_val = "ONGOING",
    ct_spec = study_ct,
    ct_clst = "C66728",
    id_vars = oak_id_vars()
  ) %>%
  # Map qualifier CMENTPT as If MDONG == 1 then CM.CMENTPT = 'DATE OF LAST ASSESSMENT'
  hardcode_no_ct(
    raw_dat = condition_add(cm_raw, MDONG == "1"),
    raw_var = "MDONG",
    tgt_var = "CMENTPT",
    tgt_val = "DATE OF LAST ASSESSMENT",
    id_vars = oak_id_vars()
  ) %>%
  # Map qualifier CMDOS as If collected value in raw_var DOS is numeric then CM.CMDOSE
  assign_no_ct(
    raw_dat = condition_add(cm_raw, is.numeric(DOS)),
    raw_var = "DOS",
    tgt_var = "CMDOS",
    id_vars = oak_id_vars()
  ) %>%
  # Map qualifier CMDOS as If collected value in raw_var DOS is character then CM.CMDOSTXT
  assign_no_ct(
    raw_dat = condition_add(cm_raw, is.character(DOS)),
    raw_var = "DOS",
    tgt_var = "CMDOSTXT",
    id_vars = oak_id_vars()
  ) %>%
  # Map qualifier CMDOSU as the collected value in the cm_raw dataset DOSU variable to CM.CMDOSU
  assign_ct(
    raw_dat = cm_raw,
    raw_var = "DOSU",
    tgt_var = "CMDOSU",
    ct_spec = study_ct,
    ct_clst = "C71620",
    id_vars = oak_id_vars()
  ) %>%
  # Map qualifier CMDOSFRM as the collected value in the cm_raw dataset MDFORM variable to CM.CMDOSFRM
  assign_ct(
    raw_dat = cm_raw,
    raw_var = "MDFORM",
    tgt_var = "CMDOSFRM",
    ct_spec = study_ct,
    ct_clst = "C66726",
    id_vars = oak_id_vars()
  ) %>%
  # Map CMROUTE as the collected value in the cm_raw dataset MDRTE variable to CM.CMROUTE
  assign_ct(
    raw_dat = cm_raw,
    raw_var = "MDRTE",
    tgt_var = "CMROUTE",
    ct_spec = study_ct,
    ct_clst = "C66729",
    id_vars = oak_id_vars()
  ) %>%
  # Map qualifier CMPROPH as If MDPROPH == 1 then CM.CMPROPH = 'Y'
  hardcode_ct(
    raw_dat = condition_add(cm_raw, MDPROPH == "1"),
    raw_var = "MDPROPH",
    tgt_var = "CMPROPH",
    tgt_val = "Y",
    ct_spec = study_ct,
    ct_clst = "C66742",
    id_vars = oak_id_vars()
  ) %>%
  # Map CMDRG as the collected value in the cm_raw dataset CMDRG variable to CM.CMDRG
  assign_no_ct(
    raw_dat = cm_raw,
    raw_var = "CMDRG",
    tgt_var = "CMDRG",
    id_vars = oak_id_vars()
  ) %>%
  # Map CMDRGCD as the collected value in the cm_raw dataset CMDRGCD variable to CM.CMDRGCD
  assign_no_ct(
    raw_dat = cm_raw,
    raw_var = "CMDRGCD",
    tgt_var = "CMDRGCD",
    id_vars = oak_id_vars()
  ) %>%
  # Map CMDECOD as the collected value in the cm_raw dataset CMDECOD variable to CM.CMDECOD
  assign_no_ct(
    raw_dat = cm_raw,
    raw_var = "CMDECOD",
    tgt_var = "CMDECOD",
    id_vars = oak_id_vars()
  ) %>%
  # Map CMPNCD as the collected value in the cm_raw dataset CMPNCD variable to CM.CMPNCD
  assign_no_ct(
    raw_dat = cm_raw,
    raw_var = "CMPNCD",
    tgt_var = "CMPNCD",
    id_vars = oak_id_vars()
  )
oak_id raw_source patient_number CMTRT CMGRPID CMDOSU CMSTDTC CMSTRTPT CMSTTPT CMDOSFRQ CMMODIFY CMINDC CMENDTC CMENRTPT CMENTPT CMDOS CMDOSTXT CMDOSFRM CMROUTE CMPROPH CMDRG CMDRGCD CMDECOD CMPNCD
1 cm_raw 375 BABY ASPIRIN 1 mg NA BEFORE SCREENING QD (EVERY DAY) NA NA ONGOING DATE OF LAST ASSESSMENT 10 NA TABLET ORAL NA BABY ASPIRIN 2701701 ACETYLSALICYLIC ACID 2701001
2 cm_raw 375 CORTISPORIN 2 g 2020-09-15 NA NA CORTISPORIN (UNITED STATES) NAUSEA NA ONGOING DATE OF LAST ASSESSMENT 50 NA PILL ORAL NA CORTICOSTEROIDS AND ANTIINFECTIVES IN COMBINATION 90104001001 CORTICOSTEROIDS AND ANTIINFECTIVES IN COMBINATION 90104001001
3 cm_raw 376 ASPIRIN 1 2021-02-17T08:00 NA NA NA ANEMIA 2021-02-17 NA NA NA NA NA ASPIRIN [ACETYLSALICYLIC ACID] 2701004 ACETYLSALICYLIC ACID 2701001
4 cm_raw 377 DIPHENHYDRAMINE HCL 1 mg 2020-10-04T09:00 NA NA BID (TWICE A DAY) NA NAUSEA NA ONGOING DATE OF LAST ASSESSMENT 50 NA CAPSULE ORAL NA DIPHENHYDRAMINE HCL 402246 DIPHENHYDRAMINE HYDROCHLORIDE 402001
5 cm_raw 377 PARCETEMOL 2 mg 2020-01-20T10:00 NA NA BID (TWICE A DAY) PYREXIA 2020-01-20T10:00 NA NA NA NA CAPSULE ORAL Y NA NA
6 cm_raw 377 VOMIKIND 3 TABLET 2019 NA NA PRN (AS NEEDED) VOMITINGS NA NA NA NA NA ORAL Y NA NA
7 cm_raw 377 ZENFLOX OZ 5 mL 2019—20T10:00 NA NA PRN (AS NEEDED) DIARHHEA NA NA NA NA NA INJECTION INTRAMUSCULAR Y NA NA
8 cm_raw 378 AMITRYPTYLINE 4 g 2020 BEFORE SCREENING QD (EVERY DAY) AMITRIPTYLINE COLD NA NA NA 12 NA INHALANT INTRA-ARTERIAL NA AMITRIPTYLINE 2201001 AMITRIPTYLINE 2201001
9 cm_raw 378 BENADRYL 1 mg 2020-01-26T09:00 NA NA BID (TWICE A DAY) BENADRYL (UNITED STATES) FEVER 2020-01-26T07:00 NA NA 100 NA CAPSULE ORAL Y BENADRYL [DIPHENHYDRAMINE HYDROCHLORIDE] 402002 DIPHENHYDRAMINE HYDROCHLORIDE 402001
10 cm_raw 378 DIPHENHYDRAMINE HYDROCHLORIDE 2 CAPSULE 2020-01-28 BEFORE SCREENING QD (EVERY DAY) NA LEG PAIN 2020-02-01 ONGOING DATE OF LAST ASSESSMENT 100 NA CAPSULE UNKNOWN NA DIPHENHYDRAMINE HYDROCHLORIDE 402001 DIPHENHYDRAMINE HYDROCHLORIDE 402001

Repeat Map Topic and Map Rest

There is only one topic variable in this raw data source, and there are no additional topic variable mappings. Users can proceed to the next step. This is required only if there is more than one topic variable to map.

Create SDTM derived variables

The SDTM derived variables or any SDTM mapping that is applicable to all the records in the cm dataset produced in the previous step cam be created now. In this example, we will create the CMSEQ variable. The mapping logic is Create a sequence number for each record in the CM domain.

cm <- cm %>%
  # The below mappings are applicable to all the records in the cm domain,
  # hence can be derived using mutate statement.
  dplyr::mutate(
    STUDYID = "test_study",
    DOMAIN = "CM",
    CMCAT = "GENERAL CONMED",
    USUBJID = paste0("test_study", "-", cm_raw$PATNUM)
  ) %>%
  # derive sequence number
  # derive_seq(tgt_var = "CMSEQ",
  #            rec_vars= c("USUBJID", "CMGRPID")) %>%
  derive_study_day(
    sdtm_in = .,
    dm_domain = dm,
    tgdt = "CMENDTC",
    refdt = "RFXSTDTC",
    study_day_var = "CMENDY"
  ) %>%
  derive_study_day(
    sdtm_in = .,
    dm_domain = dm,
    tgdt = "CMSTDTC",
    refdt = "RFXSTDTC",
    study_day_var = "CMSTDY"
  ) %>%
  # Add code for derive Baseline flag.
  dplyr::select("STUDYID", "DOMAIN", "USUBJID", everything())
oak_id raw_source patient_number STUDYID DOMAIN USUBJID CMGRPID CMTRT CMDOSU CMSTDTC CMSTRTPT CMSTTPT CMDOSFRQ CMMODIFY CMINDC CMENDTC CMENRTPT CMENTPT CMDOS CMDOSTXT CMDOSFRM CMROUTE CMPROPH CMDRG CMDRGCD CMDECOD CMPNCD CMSTDY CMENDY
1 cm_raw 375 test_study CM test_study-375 1 BABY ASPIRIN mg NA BEFORE SCREENING QD (EVERY DAY) NA NA ONGOING DATE OF LAST ASSESSMENT 10 NA TABLET ORAL NA BABY ASPIRIN 2701701 ACETYLSALICYLIC ACID 2701001 NA NA
2 cm_raw 375 test_study CM test_study-375 2 CORTISPORIN g 2020-09-15 NA NA CORTISPORIN (UNITED STATES) NAUSEA NA ONGOING DATE OF LAST ASSESSMENT 50 NA PILL ORAL NA CORTICOSTEROIDS AND ANTIINFECTIVES IN COMBINATION 90104001001 CORTICOSTEROIDS AND ANTIINFECTIVES IN COMBINATION 90104001001 -941 NA
3 cm_raw 376 test_study CM test_study-376 1 ASPIRIN 2021-02-17 NA NA NA ANEMIA 2021-02-17 NA NA NA NA NA ASPIRIN [ACETYLSALICYLIC ACID] 2701004 ACETYLSALICYLIC ACID 2701001 334 334
4 cm_raw 377 test_study CM test_study-377 1 DIPHENHYDRAMINE HCL mg 2020-10-04 NA NA BID (TWICE A DAY) NA NAUSEA NA ONGOING DATE OF LAST ASSESSMENT 50 NA CAPSULE ORAL NA DIPHENHYDRAMINE HCL 402246 DIPHENHYDRAMINE HYDROCHLORIDE 402001 205 NA
5 cm_raw 377 test_study CM test_study-377 2 PARCETEMOL mg 2020-01-20 NA NA BID (TWICE A DAY) PYREXIA 2020-01-20 NA NA NA NA CAPSULE ORAL Y NA NA -54 -54
6 cm_raw 377 test_study CM test_study-377 3 VOMIKIND TABLET NA NA NA PRN (AS NEEDED) VOMITINGS NA NA NA NA NA ORAL Y NA NA NA NA
7 cm_raw 377 test_study CM test_study-377 5 ZENFLOX OZ mL NA NA NA PRN (AS NEEDED) DIARHHEA NA NA NA NA NA INJECTION INTRAMUSCULAR Y NA NA NA NA
8 cm_raw 378 test_study CM test_study-378 4 AMITRYPTYLINE g NA BEFORE SCREENING QD (EVERY DAY) AMITRIPTYLINE COLD NA NA NA 12 NA INHALANT INTRA-ARTERIAL NA AMITRIPTYLINE 2201001 AMITRIPTYLINE 2201001 NA NA
9 cm_raw 378 test_study CM test_study-378 1 BENADRYL mg 2020-01-26 NA NA BID (TWICE A DAY) BENADRYL (UNITED STATES) FEVER 2020-01-26 NA NA 100 NA CAPSULE ORAL Y BENADRYL [DIPHENHYDRAMINE HYDROCHLORIDE] 402002 DIPHENHYDRAMINE HYDROCHLORIDE 402001 -377 -377
10 cm_raw 378 test_study CM test_study-378 2 DIPHENHYDRAMINE HYDROCHLORIDE CAPSULE 2020-01-28 BEFORE SCREENING QD (EVERY DAY) NA LEG PAIN 2020-02-01 ONGOING DATE OF LAST ASSESSMENT 100 NA CAPSULE UNKNOWN NA DIPHENHYDRAMINE HYDROCHLORIDE 402001 DIPHENHYDRAMINE HYDROCHLORIDE 402001 -375 -371

Add Labels and Attributes

Yet to be developed.