← CDISC notebook index

Map Raw Demographics to SDTM-Compliant DM

Open In Colab

Author: Alpha Traore, Sr Data Scientist, Biostat Consultants Inc.
📁 Project: CDISC Dataset Preparation
📁 Domain: DM (Demographics)
🎯 Purpose: Mapping Raw Clinical Data to SDTM DM Domain Using R


📌Overview

This notebook demonstrates the process of creating the Demographics (DM) domain as defined by the CDISC SDTM model. The objective is to use R to program a compliant DM dataset, suitable for clinical trial data submissions and regulatory review.

Step 1: Load Raw Data Inputs

load("dm_rawdata.RData")
ls()
  1. 'adverse'
  2. 'box'
  3. 'conmeds'
  4. 'demog'
  5. 'ecg'
  6. 'eligcrit'
  7. 'enrlment'
  8. 'eoip'
  9. 'eos'
  10. 'eq5d3l'
  11. 'hosp'
  12. 'ipadmin'
  13. 'lab_chem'
  14. 'lab_hema'
  15. 'My_packages'
  16. 'physmeas'
  17. 'rand'
  18. 'surg'
  19. 'vitals'

Step 2: Check Demog Raw data

# load("dm_rawdata.RData", nv <- new.env())
# ls(nv)
demog
A tibble: 8 × 13
studyptsexethnicracerace2race3race4racespage_rawage_rawubrthdt_rawcountry
<chr><chr><chr><chr><chr><chr><chr><chr><chr><chr><chr><chr><chr>
CSG0011001Male Hispanic or Latino White 35YearsUSA
CSG0011002FemaleNot Hispanic or LatinoAsian American Indian or Alaska Native 40YearsUSA
CSG0011003Male Hispanic or Latino Other BRAZILIAN40YearsUSA
CSG0011004Male Hispanic or Latino White 38YearsUSA
CSG0011005Male Not Hispanic or LatinoAmerican Indian or Alaska Native 64YearsUSA
CSG0011006FemaleNot Hispanic or LatinoNative Hawaiian or Other Pacific Islander 75YearsUSA
CSG0011007Male Not Hispanic or LatinoUnknown 32YearsUSA
CSG0011008FemaleNot Hispanic or LatinoNot Reported 83YearsUSA

3. Generate the identifier variables and additional variables that are directly contingent upon the raw variables, without engaging in significant derivations.

dm01 <- demog %>%
 rename(race0 = race) %>%
 mutate(
 domain = "DM",
 studyid = study,
 subjid = pt,
 siteid = substr(pt, 1, 2),
 usubjid = paste(study, pt, sep = "-"),
 country = country,
 ethnic = toupper(ethnic),
 non_missing_count = rowSums(across(c(race0, race2, race3, race4), ~ !is.na(.) & . != "")),

 race = ifelse(non_missing_count > 1, "MULTIPLE", toupper(coalesce(race0, race2, race3, race4))),
 racesp = racesp,
 race1 = ifelse(non_missing_count > 1,toupper(race0),""),
 race2 = ifelse(non_missing_count > 1,toupper(race2),""),
 race3 = ifelse(non_missing_count > 1,toupper(race3),""),
 race4 = ifelse(non_missing_count > 1,toupper(race4),""),

 age = ifelse(!is.na(age_raw), as.integer(age_raw), NA_integer_),
 ageu = toupper(age_rawu),
 sex = ifelse(sex == "Female", "F", ifelse(sex == "Male", "M", sex))
 )
 select(dm01, c('domain','studyid','subjid', 'siteid','usubjid','country', 'ethnic','race','age','ageu','sex'))
A tibble: 8 × 11
domainstudyidsubjidsiteidusubjidcountryethnicraceageageusex
<chr><chr><chr><chr><chr><chr><chr><chr><int><chr><chr>
DMCSG001100110CSG001-1001USAHISPANIC OR LATINO WHITE 35YEARSM
DMCSG001100210CSG001-1002USANOT HISPANIC OR LATINOMULTIPLE 40YEARSF
DMCSG001100310CSG001-1003USAHISPANIC OR LATINO OTHER 40YEARSM
DMCSG001100410CSG001-1004USAHISPANIC OR LATINO WHITE 38YEARSM
DMCSG001100510CSG001-1005USANOT HISPANIC OR LATINOAMERICAN INDIAN OR ALASKA NATIVE 64YEARSM
DMCSG001100610CSG001-1006USANOT HISPANIC OR LATINONATIVE HAWAIIAN OR OTHER PACIFIC ISLANDER75YEARSF
DMCSG001100710CSG001-1007USANOT HISPANIC OR LATINOUNKNOWN 32YEARSM
DMCSG001100810CSG001-1008USANOT HISPANIC OR LATINONOT REPORTED 83YEARSF

4. Check the new variables

select(dm01, c('domain','studyid','subjid', 'siteid','usubjid','country', 'ethnic','race','age','ageu','sex'))
A tibble: 8 × 11
domainstudyidsubjidsiteidusubjidcountryethnicraceageageusex
<chr><chr><chr><chr><chr><chr><chr><chr><int><chr><chr>
DMCSG001100110CSG001-1001USAHISPANIC OR LATINO WHITE 35YEARSM
DMCSG001100210CSG001-1002USANOT HISPANIC OR LATINOMULTIPLE 40YEARSF
DMCSG001100310CSG001-1003USAHISPANIC OR LATINO OTHER 40YEARSM
DMCSG001100410CSG001-1004USAHISPANIC OR LATINO WHITE 38YEARSM
DMCSG001100510CSG001-1005USANOT HISPANIC OR LATINOAMERICAN INDIAN OR ALASKA NATIVE 64YEARSM
DMCSG001100610CSG001-1006USANOT HISPANIC OR LATINONATIVE HAWAIIAN OR OTHER PACIFIC ISLANDER75YEARSF
DMCSG001100710CSG001-1007USANOT HISPANIC OR LATINOUNKNOWN 32YEARSM
DMCSG001100810CSG001-1008USANOT HISPANIC OR LATINONOT REPORTED 83YEARSF
enrlment
A tibble: 8 × 9
studyptfoldericdt_rawicversprtversenrldt_rawranddt_rawrandno
<chr><chr><chr><chr><chr><chr><chr><chr><chr>
CSG0011001SCR1/JAN/2010 11
CSG0011002SCR1/JAN/2010 114/JAN/2010
CSG0011003SCR1/JAN/2010 113/JAN/2010 3/JAN/2010 514876
CSG0011004SCR1/JAN/2010 114/JAN/2010 5/JAN/2010 101415
CSG0011005SCR15/JAN/2010111/FEB/2010 5/FEB/2010 306185
CSG0011006SCR18/FEB/2010111/MAR/2010 1/MAR/2010 987435
CSG0011007SCR4/APR/2010 2214/APR/201014/APR/2010098745
CSG0011008SCR20/JUN/20102326/JUN/201027/JUN/2010123098

Derive disposition related variables

rficdtc <- enrlment %>%
 mutate(
 rficdtc = ifelse(!is.na(icdt_raw), format(as.Date(icdt_raw, format = "%d/%b/%Y"),"%Y-%m-%d"), NA),
 enrldtc = ifelse(!is.na(enrldt_raw), format(as.Date(enrldt_raw, format = "%d/%b/%Y"),"%Y-%m-%d"), NA),
 randdtc = ifelse(!is.na(randdt_raw), format(as.Date(randdt_raw, format = "%d/%b/%Y"),"%Y-%m-%d"), NA)
 ) %>%
 select(study, pt, rficdtc, enrldtc, randdtc)

rfendtc <- eos %>%
 filter(eoscat == "End of Study") %>%
 mutate(rfendtc = ifelse(!is.na(eostdt_raw), format(as.Date(eostdt_raw, format = "%d/%b/%Y"),"%Y-%m-%d"), NA)) %>%
 select(study, pt, rfendtc)

dthdtc <- eos %>%
 filter(eoscat == "End of Study" & eoterm == "Death") %>%
 mutate(dthdtc = ifelse(!is.na(eostdt_raw), format(as.Date(eostdt_raw, format = "%d/%b/%Y"),"%Y-%m-%d"), NA), dthfl = "Y") %>%
 select(study, pt, dthdtc, dthfl)
rficdtc
A tibble: 8 × 5
studyptrficdtcenrldtcranddtc
<chr><chr><chr><chr><chr>
CSG00110012010-01-01NA NA
CSG00110022010-01-012010-01-04NA
CSG00110032010-01-012010-01-032010-01-03
CSG00110042010-01-012010-01-042010-01-05
CSG00110052010-01-152010-02-012010-02-05
CSG00110062010-02-182010-03-012010-03-01
CSG00110072010-04-042010-04-142010-04-14
CSG00110082010-06-202010-06-262010-06-27
rfendtc
A tibble: 6 × 3
studyptrfendtc
<chr><chr><chr>
CSG00110022010-01-05
CSG00110032010-01-05
CSG00110042010-02-28
CSG00110062010-03-25
CSG00110072010-06-12
CSG00110082010-08-18
dthdtc
A tibble: 1 × 4
studyptdthdtcdthfl
<chr><chr><chr><chr>
CSG00110032010-01-05Y

Get Exposure Related Variables

exp01 <- ipadmin %>%
 filter(as.integer(ipqty_raw) > 0) %>%
 mutate(
 ipstdtc = as.Date(ipstdt_raw, format = "%d/%b/%Y"),
 ipsttm = format(as.POSIXct(ipsttm_raw, format = "%H:%M", tz = ""),"%H:%M"),
 tempdtc = paste(ipstdtc, ipsttm, sep = "T")
 ) %>%
 select(study, pt, tempdtc, ipboxid)

#Earliest treatment date
rfxstdtc <- exp01 %>%
 arrange(study,pt,tempdtc) %>%
 group_by(study, pt) %>%
 slice(1) %>%
 mutate(rfxstdtc = tempdtc)

#Late treatment date
rfxendtc <- exp01 %>%
 arrange(study,pt,tempdtc) %>%
 group_by(study, pt) %>%
 slice(n()) %>%
 mutate(rfxendtc = tempdtc)
exp01
A tibble: 15 × 4
studypttempdtcipboxid
<chr><chr><chr><chr>
CSG00110042010-01-05T08:3513434371
CSG00110042010-01-12T08:3552970539
CSG00110042010-01-18T09:3052120567
CSG00110042010-01-25T08:4559305202
CSG00110052010-02-05T08:4613787377
CSG00110052010-02-12T08:3065580239
CSG00110062010-03-02T08:3039024101
CSG00110062010-03-10T08:3065845489
CSG00110072010-04-15T08:2366223983
CSG00110072010-04-22T09:0071763169
CSG00110072010-04-29T09:0360038358
CSG00110072010-05-06T08:1268706162
CSG00110082010-06-27T08:4568891589
CSG00110082010-07-04T08:172311359
CSG00110082010-07-11T09:203199027
rfxstdtc
A grouped_df: 5 × 5
studypttempdtcipboxidrfxstdtc
<chr><chr><chr><chr><chr>
CSG00110042010-01-05T08:35134343712010-01-05T08:35
CSG00110052010-02-05T08:46137873772010-02-05T08:46
CSG00110062010-03-02T08:30390241012010-03-02T08:30
CSG00110072010-04-15T08:23662239832010-04-15T08:23
CSG00110082010-06-27T08:45688915892010-06-27T08:45
rfxendtc
A grouped_df: 5 × 5
studypttempdtcipboxidrfxendtc
<chr><chr><chr><chr><chr>
CSG00110042010-01-25T08:45593052022010-01-25T08:45
CSG00110052010-02-12T08:30655802392010-02-12T08:30
CSG00110062010-03-10T08:30658454892010-03-10T08:30
CSG00110072010-05-06T08:12687061622010-05-06T08:12
CSG00110082010-07-11T09:203199027 2010-07-11T09:20

Derive Planned and Actual Arm related variables

randno <- enrlment %>%
 filter(!is.na(randno) & randno!="") %>%
 select(study, pt, randno)

rand01 <- rand %>%
 mutate(
 armcd = tx_cd,
 arm = ifelse(armcd == "ACTIVE", "Active", ifelse(armcd == "PBO", "Placebo", NA_character_))
 ) %>%
 select(armcd, arm, randno=rand_id)

armcd <- randno %>%
 left_join(rand01, by = "randno")
randno
A tibble: 6 × 3
studyptrandno
<chr><chr><chr>
CSG0011003514876
CSG0011004101415
CSG0011005306185
CSG0011006987435
CSG0011007098745
CSG0011008123098
rand01
A tibble: 6 × 3
armcdarmrandno
<chr><chr><chr>
PBO Placebo514876
ACTIVEActive 101415
ACTIVEActive 306185
PBO Placebo987435
PBO Placebo098745
ACTIVEActive 123098
armcd
A tibble: 6 × 5
studyptrandnoarmcdarm
<chr><chr><chr><chr><chr>
CSG0011003514876PBO Placebo
CSG0011004101415ACTIVEActive
CSG0011005306185ACTIVEActive
CSG0011006987435PBO Placebo
CSG0011007098745PBO Placebo
CSG0011008123098ACTIVEActive

Derive actual related variable

actarmcd01 <- rfxstdtc

# Create 'box01' data frame
box01 <- box %>%
 mutate(
 ipboxid = kitid,
 actarmcd = case_when(
 content == "ACTIVE" ~ "ACTIVE",
 content == "PBO" ~ "PBO",
 TRUE ~ NA_character_
 ),
 actarm = case_when(
 content == "ACTIVE" ~ "Active",
 content == "PBO" ~ "Placebo",
 TRUE ~ NA_character_
 )
 )

# Merge 'actarmcd01' and 'box01' data frames by 'ipboxid'
actarmcd <- left_join(actarmcd01, box01, by = "ipboxid") %>%
 filter(!is.na(actarmcd)) %>%
 select(study, pt, actarmcd, actarm)
actarmcd
A grouped_df: 5 × 4
studyptactarmcdactarm
<chr><chr><chr><chr>
CSG0011004ACTIVEActive
CSG0011005PBO Placebo
CSG0011006PBO Placebo
CSG0011007PBO Placebo
CSG0011008ACTIVEActive

RFPENDTC;

# Combine the raw date variables into 'alldates01' data frame
alldates01 <- bind_rows(
 adverse %>% select(study, pt, date = aestdt_raw),
 adverse %>% select(study, pt, date = aeendt_raw),
 adverse %>% select(study, pt, date = hadmtdt_raw),
 adverse %>% select(study, pt, date = hdsdt_raw),
 conmeds %>% select(study, pt, date = cmstdt_raw),
 conmeds %>% select(study, pt, date = cmendt_raw),
 ecg %>% select(study, pt, date = egdt_raw),
 enrlment %>% select(study, pt, date = icdt_raw),
 enrlment %>% select(study, pt, date = enrldt_raw),
 enrlment %>% select(study, pt, date = randdt_raw),
 eos %>% select(study, pt, date = eostdt_raw),
 eoip %>% select(study, pt, date = eostdt_raw),
 eq5d3l %>% select(study, pt, date = dt_raw),
 hosp %>% select(study, pt, date = stdt_raw),
 hosp %>% select(study, pt, date = endt_raw),
 ipadmin %>% select(study, pt, date = ipstdt_raw),
 lab_chem %>% select(study, pt, date = lbdt_raw),
 lab_hema %>% select(study, pt, date = lbdt_raw),
 physmeas %>% select(study, pt, date = pmdt_raw),
 surg %>% select(study, pt, date = surgdt_raw),
 vitals %>% select(study, pt, date = vsdt_raw)
)
alldates01
A tibble: 953 × 3
studyptdate
<chr><chr><chr>
CSG001100101/JAN/2010
CSG001100305/JAN/2010
CSG001100401/JAN/2010
CSG001100403/JAN/2010
CSG001100408/JAN/2010
CSG001100410/JAN/2010
CSG001100518/FEB/2010
CSG0011006UN/MAR/2010
CSG00110079/MAY/2010
CSG001100101/JAN/2010
CSG001100305/JAN/2010
CSG001100401/JAN/2010
CSG001100407/JAN/2010
CSG001100409/JAN/2010
CSG0011004
CSG001100521/FEB/2010
CSG001100625/MAR/2010
CSG001100712/MAY/2010
CSG0011001
CSG00110035/JAN/2010
CSG0011004
CSG0011004
CSG0011004
CSG0011004
CSG001100520/FEB/2020
CSG0011006
CSG0011007
CSG0011001
CSG00110035/JAN/2010
CSG0011004
CSG001100811/Jul/2010
CSG001100811/Jul/2010
CSG001100811/Jul/2010
CSG001100811/Jul/2010
CSG001100811/Jul/2010
CSG001100811/Jul/2010
CSG001100811/Jul/2010
CSG001100811/Jul/2010
CSG001100811/Jul/2010
CSG001100811/Jul/2010
CSG001100811/Jul/2010
CSG001100811/Jul/2010
CSG001100811/Jul/2010
CSG001100811/Jul/2010
CSG001100811/Jul/2010
CSG001100811/Jul/2010
CSG00110044/JAN/2010
CSG00110055/FEB/2010
CSG00110061/MAR/2010
CSG001100713/APR/2010
CSG001100520/FEB/2010
CSG001100402/JAN/2010
CSG001100412/JAN/2010
CSG00110055/FEB/2010
CSG001100512/FEB/2010
CSG001100522/FEB/2010
CSG001100601/MAR/2010
CSG001100611/MAR/2010
CSG001100715/APR/2010
CSG001100729/APR/2010
# Process the date variables to create date in ISO format sprintf("in 'alldates02' data frame
alldates02 <- alldates01 %>%
 mutate(
     dayn = suppressWarnings(as.numeric(word(date, 1, sep='/'))),
     daync = sprintf("%02d", dayn),
     day =suppressWarnings(as.numeric(word(date, 1, sep='/'))),

     monthc = toupper(word(date, 2, sep='/')),
     month = case_when(
         monthc == "JAN" ~ "01",
         monthc == "FEB" ~ "02",
         monthc == "MAR" ~ "03",
         monthc == "APR" ~ "04",
         monthc == "MAY" ~ "05",
         monthc == "JUN" ~ "06",
         monthc == "JUL" ~ "07",
         monthc == "AUG" ~ "08",
         monthc == "SEP" ~ "09",
         monthc == "OCT" ~ "10",
         monthc == "NOV" ~ "11",
         monthc == "DEC" ~ "12",
         TRUE ~ "-"
     ),

 year = word(date,3,sep='/'),
 year = if_else(toupper(year) == "UNK", "-", year),

 # datec = str_c(year, month, day, sep = "-"),
 datec = str_c(year, month, daync, sep = "-"),

 datec = ifelse(str_sub(datec, -5) == "-----", str_sub(datec, end = -6), datec),
 datec = ifelse(str_sub(datec, -4) == "----", str_sub(datec, end = -5), datec),
 datec = ifelse(str_sub(datec, -2) == "--", str_sub(datec, end = -3), datec)

 )


alldates03 <-na.omit(alldates02)


# Pick the latest non-missing date for each subject
rfpendtc <- alldates03 %>%
 filter(!is.na(datec) & datec != "") %>%
 arrange(study, pt, datec) %>%
 group_by(study, pt) %>%
 slice(n()) %>%
 ungroup() %>%
 select(study, pt, rfpendtc = datec)
alldates03
A tibble: 932 × 10
studyptdatedayndayncdaymonthcmonthyeardatec
<chr><chr><chr><dbl><chr><dbl><chr><chr><chr><chr>
CSG001100101/JAN/2010 101 1JAN0120102010-01-01
CSG001100305/JAN/2010 505 5JAN0120102010-01-05
CSG001100401/JAN/2010 101 1JAN0120102010-01-01
CSG001100403/JAN/2010 303 3JAN0120102010-01-03
CSG001100408/JAN/2010 808 8JAN0120102010-01-08
CSG001100410/JAN/2010101010JAN0120102010-01-10
CSG001100518/FEB/2010181818FEB0220102010-02-18
CSG00110079/MAY/2010 909 9MAY0520102010-05-09
CSG001100101/JAN/2010 101 1JAN0120102010-01-01
CSG001100305/JAN/2010 505 5JAN0120102010-01-05
CSG001100401/JAN/2010 101 1JAN0120102010-01-01
CSG001100407/JAN/2010 707 7JAN0120102010-01-07
CSG001100409/JAN/2010 909 9JAN0120102010-01-09
CSG001100521/FEB/2010212121FEB0220102010-02-21
CSG001100625/MAR/2010252525MAR0320102010-03-25
CSG001100712/MAY/2010121212MAY0520102010-05-12
CSG00110035/JAN/2010 505 5JAN0120102010-01-05
CSG001100520/FEB/2020202020FEB0220202020-02-20
CSG00110035/JAN/2010 505 5JAN0120102010-01-05
CSG001100520/FEB/2020202020FEB0220202020-02-20
CSG00110066/MAR/2010 606 6MAR0320102010-03-06
CSG001100710/MAY/2010101010MAY0520102010-05-10
CSG001100625/MAR/2010252525MAR0320102010-03-25
CSG001100712/MAY/2010121212MAY0520102010-05-12
CSG00110044/JAN/2010 404 4JAN0120102010-01-04
CSG00110055/FEB/2010 505 5FEB0220102010-02-05
CSG001100522/FEB/2010222222FEB0220102010-02-22
CSG00110061/MAR/2010 101 1MAR0320102010-03-01
CSG001100713/APR/2010131313APR0420102010-04-13
CSG00110011/JAN/2010 101 1JAN0120102010-01-01
CSG001100811/Jul/2010111111JUL0720102010-07-11
CSG001100811/Jul/2010111111JUL0720102010-07-11
CSG001100811/Jul/2010111111JUL0720102010-07-11
CSG001100811/Jul/2010111111JUL0720102010-07-11
CSG001100811/Jul/2010111111JUL0720102010-07-11
CSG001100811/Jul/2010111111JUL0720102010-07-11
CSG001100811/Jul/2010111111JUL0720102010-07-11
CSG001100811/Jul/2010111111JUL0720102010-07-11
CSG001100811/Jul/2010111111JUL0720102010-07-11
CSG001100811/Jul/2010111111JUL0720102010-07-11
CSG001100811/Jul/2010111111JUL0720102010-07-11
CSG001100811/Jul/2010111111JUL0720102010-07-11
CSG001100811/Jul/2010111111JUL0720102010-07-11
CSG001100811/Jul/2010111111JUL0720102010-07-11
CSG001100811/Jul/2010111111JUL0720102010-07-11
CSG001100811/Jul/2010111111JUL0720102010-07-11
CSG00110044/JAN/2010 404 4JAN0120102010-01-04
CSG00110055/FEB/2010 505 5FEB0220102010-02-05
CSG00110061/MAR/2010 101 1MAR0320102010-03-01
CSG001100713/APR/2010131313APR0420102010-04-13
CSG001100520/FEB/2010202020FEB0220102010-02-20
CSG001100402/JAN/2010 202 2JAN0120102010-01-02
CSG001100412/JAN/2010121212JAN0120102010-01-12
CSG00110055/FEB/2010 505 5FEB0220102010-02-05
CSG001100512/FEB/2010121212FEB0220102010-02-12
CSG001100522/FEB/2010222222FEB0220102010-02-22
CSG001100601/MAR/2010 101 1MAR0320102010-03-01
CSG001100611/MAR/2010111111MAR0320102010-03-11
CSG001100715/APR/2010151515APR0420102010-04-15
CSG001100729/APR/2010292929APR0420102010-04-29
rfpendtc
A tibble: 8 × 3
studyptrfpendtc
<chr><chr><chr>
CSG00110012010-01-01
CSG00110022010-01-05
CSG00110032010-01-05
CSG00110042010-02-28
CSG00110052020-02-20
CSG00110062010-03-25
CSG00110072010-06-12
CSG00110082010-08-18

Merge all datasets together

dm02 <- dm01 %>%
 left_join(rficdtc, by = c("study", "pt")) %>%
 left_join(dthdtc, by = c("study", "pt")) %>%
 left_join(rfendtc, by = c("study", "pt")) %>%
 left_join(rfxstdtc, by = c("study", "pt")) %>%
 left_join(rfxendtc, by = c("study", "pt")) %>%
 left_join(armcd, by = c("study", "pt")) %>%
 left_join(actarmcd, by = c("study", "pt")) %>%
 left_join(rfpendtc, by = c("study", "pt"))

Derive additional variables which are dependent on other derived variables

dm03 <- dm02 %>%
 mutate(
 rfstdtc = substr(rfxstdtc, 1, 10),
 rfstdtc = ifelse(is.na(rfstdtc) & !is.na(randdtc), randdtc, rfstdtc),
 rfstdtc = ifelse(is.na(rfstdtc) & !is.na(rficdtc), rficdtc, rfstdtc),

 armcd = case_when(
 is.na(enrldtc) ~ "SCRNFAIL",
 is.na(randdtc) ~ "NOTASSGN",
 TRUE ~ armcd
 ),

 arm = case_when(
 armcd =="SCRNFAIL" ~ "Screen Failure",
 armcd == "NOTASSGN" ~ "Not Assigned",
 TRUE ~ arm),

 actarmcd = case_when(
 is.na(enrldtc) ~ "SCRNFAIL",
 is.na(randdtc) ~ "NOTASSGN",
 is.na(rfxstdtc) ~ "NOTTRT",
 TRUE ~ actarmcd
 ),

 actarm = case_when(
 actarmcd =="SCRNFAIL" ~ "Screen Failure",
 actarmcd == "NOTASSGN" ~ "Not Assigned",
 actarmcd == "NOTTRT" ~ "Not Treated",
 TRUE ~ actarm),

 ) %>%
 rename_all(toupper)

# Write attributes and keep only required variables and in the required order
varlist <- c(
 'STUDYID', 'DOMAIN', 'USUBJID', 'SUBJID', 'RFSTDTC', 'RFENDTC', 'RFXSTDTC', 'RFXENDTC',
 'RFICDTC', 'RFPENDTC', 'DTHDTC', 'DTHFL', 'SITEID', 'AGE', 'AGEU', 'SEX', 'RACE', 'ETHNIC',
 'ARMCD', 'ARM', 'ACTARMCD', 'ACTARM', 'COUNTRY', 'RACE'
)

dm <- dm03 %>%
 select(all_of(varlist))

output <- dm
View(dm)
A tibble: 8 × 23
STUDYIDDOMAINUSUBJIDSUBJIDRFSTDTCRFENDTCRFXSTDTCRFXENDTCRFICDTCRFPENDTCAGEAGEUSEXRACEETHNICARMCDARMACTARMCDACTARMCOUNTRY
<chr><chr><chr><chr><chr><chr><chr><chr><chr><chr><int><chr><chr><chr><chr><chr><chr><chr><chr><chr>
CSG001DMCSG001-100110012010-01-01NA NA NA 2010-01-012010-01-0135YEARSMWHITE HISPANIC OR LATINO SCRNFAILScreen FailureSCRNFAILScreen FailureUSA
CSG001DMCSG001-100210022010-01-012010-01-05NA NA 2010-01-012010-01-0540YEARSFMULTIPLE NOT HISPANIC OR LATINONOTASSGNNot Assigned NOTASSGNNot Assigned USA
CSG001DMCSG001-100310032010-01-032010-01-05NA NA 2010-01-012010-01-0540YEARSMOTHER HISPANIC OR LATINO PBO Placebo NOTTRT Not Treated USA
CSG001DMCSG001-100410042010-01-052010-02-282010-01-05T08:352010-01-25T08:452010-01-012010-02-2838YEARSMWHITE HISPANIC OR LATINO ACTIVE Active ACTIVE Active USA
CSG001DMCSG001-100510052010-02-05NA 2010-02-05T08:462010-02-12T08:302010-01-152020-02-2064YEARSMAMERICAN INDIAN OR ALASKA NATIVE NOT HISPANIC OR LATINOACTIVE Active PBO Placebo USA
CSG001DMCSG001-100610062010-03-022010-03-252010-03-02T08:302010-03-10T08:302010-02-182010-03-2575YEARSFNATIVE HAWAIIAN OR OTHER PACIFIC ISLANDERNOT HISPANIC OR LATINOPBO Placebo PBO Placebo USA
CSG001DMCSG001-100710072010-04-152010-06-122010-04-15T08:232010-05-06T08:122010-04-042010-06-1232YEARSMUNKNOWN NOT HISPANIC OR LATINOPBO Placebo PBO Placebo USA
CSG001DMCSG001-100810082010-06-272010-08-182010-06-27T08:452010-07-11T09:202010-06-202010-08-1883YEARSFNOT REPORTED NOT HISPANIC OR LATINOACTIVE Active ACTIVE Active USA
save(dm, file = "C:/Users/Waraba/Desktop/Ckinical Trial Training Materiels/SDTM_withR/SDTM_EXAMPLE/SDTM_FINAL_DATA/dm.RData")
write.csv(dm, "C:/Users/Waraba/Desktop/Ckinical Trial Training Materiels/SDTM_withR/SDTM_EXAMPLE/SDTM_FINAL_DATA/dm.csv", row.names = FALSE)
write_xpt(dm, "dm.xpt")
colnames(dm)
  1. 'STUDYID'
  2. 'DOMAIN'
  3. 'USUBJID'
  4. 'SUBJID'
  5. 'RFSTDTC'
  6. 'RFENDTC'
  7. 'RFXSTDTC'
  8. 'RFXENDTC'
  9. 'RFICDTC'
  10. 'RFPENDTC'
  11. 'DTHDTC'
  12. 'DTHFL'
  13. 'SITEID'
  14. 'AGE'
  15. 'AGEU'
  16. 'SEX'
  17. 'RACE'
  18. 'ETHNIC'
  19. 'ARMCD'
  20. 'ARM'
  21. 'ACTARMCD'
  22. 'ACTARM'
  23. 'COUNTRY'

📬 Contacts

Your comments and questions are valued and encouraged. Please feel free to contact the author:

Alpha Traore
Sr Data Scientist
Biostat Consultants Inc.
312 Ridgewood Pl
Fort Thomas, KY 41075
📧
🔗 [LinkedIn Profile] (https://www.linkedin.com/in/alphatraore)