Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SERREAS derivation in AEL03 needs correction #269

Closed
kathrinflunkert opened this issue Sep 30, 2024 · 9 comments · Fixed by #284
Closed

SERREAS derivation in AEL03 needs correction #269

kathrinflunkert opened this issue Sep 30, 2024 · 9 comments · Fixed by #284
Assignees
Labels
question Further information is requested sme

Comments

@kathrinflunkert
Copy link

There can be multiple reasons why an AE was serious, e.g. required hospitalization and was life-threatening. In these cases the listing should display both these reasons as "2, 3", but with the current case-when setup it would only ever display one reason.

@Melkiades
Copy link
Contributor

Hi @kathrinflunkert could you provide a reproducible example that highlights the issue? Thanks!

@Melkiades Melkiades added question Further information is requested sme labels Sep 30, 2024
@kathrinflunkert
Copy link
Author

Here is a reproducible example where I changed AESLIFE for one subject to 'Y' so that this patients has two records where AESLIFE == "Y" and AESHOSP == "Y" (i.e. two Reasons classified as serious are present):

library(chevron)
library(dplyr)
library(rlistings)

data <- chevron::syn_data

data$adae <- data$adae %>%
  filter(USUBJID=='AB12345-BRA-11-id-9')%>%
  dplyr::mutate(
    AESLIFE = factor(ifelse(USUBJID=='AB12345-BRA-11-id-9' & AESER=='Y', 'Y', as.character(AESLIFE)))
    )

The code below is taken from the TLG Catalog:

# The below code is taken from 
out <- data$adae %>%
  filter(AESER == "Y") %>%
  mutate(
    CPID = paste(SITEID, SUBJID, sep = "/"),
    ASR = paste(AGE, SEX, RACE, sep = "/"),
    Date_First = toupper(format(as.Date(TRTSDTM), "%d%b%Y")),
    Duration = AENDY - ASTDY + 1,
    Related = ifelse(AEREL == "Y", "Yes", ifelse(AEREL == "N", "No", "")),
    Outcome = case_when(
      AEOUT == "FATAL" ~ 1,
      AEOUT == "NOT RECOVERED/NOT RESOLVED" ~ 2,
      AEOUT == "RECOVERED/RESOLVED" ~ 3,
      AEOUT == "RECOVERED/RESOLVED WITH SEQUELAE" ~ 4,
      AEOUT == "RECOVERING/RESOLVING" ~ 5,
      AEOUT == "UNKNOWN" ~ 6
    ),
    Treated = ifelse(AECONTRT == "Y", "Yes", ifelse(AECONTRT == "N", "No", "")),
    Action = case_when(
      AEACN == "DOSE INCREASED" ~ 1,
      AEACN == "DOSE NOT CHANGED" ~ 2,
      AEACN == "DOSE REDUCED" | AEACN == "DOSE RATE REDUCED" ~ 3,
      AEACN == "DRUG INTERRUPTED" ~ 4,
      AEACN == "DRUG WITHDRAWN" ~ 5,
      AEACN == "NOT APPLICABLE" | AEACN == "NOT EVALUABLE" ~ 6,
      AEACN == "UNKNOWN" ~ 7
    ),
    SERREAS = case_when(
      AESDTH == "Y" ~ "1",
      AESLIFE == "Y" ~ "2",
      AESHOSP == "Y" ~ "3",
      AESDISAB == "Y" ~ "4",
      AESCONG == "Y" ~ "5",
      AESMIE == "Y" ~ "6",
      TRUE ~ " "
    )
  ) %>%
  select(CPID, ASR, TRT01A, AEDECOD, Date_First, ASTDY, Duration, AESEV, Related, Outcome, Treated, Action, SERREAS)

var_labels(out) <- c(
  CPID = "Center/Patient ID",
  ASR = "Age/Sex/Race",
  TRT01A = "Treatment",
  AEDECOD = "Adverse\nEvent MedDRA\nPreferred Term",
  Date_First = "Date of\nFirst Study\nDrug\nAdministration",
  ASTDY = "Study\nDay of\nOnset",
  Duration = "AE\nDuration\nin Days",
  AESEV = "Most\nExtreme\nIntensity",
  Related = "Caused by\nStudy\nDrug",
  Outcome = "Outcome\n(1)",
  Treated = "Treatment\nfor AE",
  Action = "Action\nTaken\n(2)",
  SERREAS = "Reason\nClassified\nas Serious\n(3)"
)

lsting <- as_listing(
  out,
  key_cols = c("TRT01A", "CPID", "ASR"),
  disp_cols = names(out),
  main_title = "Listing of Serious Adverse Events",
  main_footer = "
(1) Outcome: 1 = fatal; 2 = not recovered/not resolved; 3 = recovered/resolved;
    4 = recovered/resolved with sequelae; 5 = recovering/resolving; 6 = unknown.
(2) Action taken with study drug: 1 = dose increased; 2 = dose not changed;
    3 = dose reduced; 4 = drug interrupted; 5 = drug withdrawn; 6 = not applicable;
    7 = unknown.
(3) Reason classified as serious: 1 = resulted in death; 2 = life threatening;
    3 = required prolonged in patient hospitalization; 4 = disabling;
    5 = a congenital anomaly/birth defect in offspring of study subject;
    6 = does not meet any of the above serious criteria, but may jeopardize the subject,
    and may require medical or surgical intervention to prevent one of the outcomes listed above.
*  Study day derived from imputed onset date.
** Duration derived from imputed onset date and/or end date."
)

head(lsting, 20)

The resulting list only shows one of the two Reasons classified as serious in the very last column even though there are two reasons present in the data.

Listing of Serious Adverse Events

———————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
                                                                        Date of                                                                                    Reason  
                                                       Adverse        First Study     Study       AE        Most      Caused by                         Action   Classified
                                                     Event MedDRA         Drug        Day of   Duration    Extreme      Study     Outcome   Treatment   Taken    as Serious
  Treatment      Center/Patient ID   Age/Sex/Race   Preferred Term   Administration   Onset    in Days    Intensity     Drug        (1)      for AE      (2)        (3)    
———————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
C: Combination      BRA-11/id-9       40/M/ASIAN    dcd B.2.2.3.1      25MAR2019       441        53        MILD         No          5         No         2          2     
                                                    dcd D.1.1.1.1      25MAR2019       445       598       SEVERE        Yes         1         No         6          1     
                                                    dcd B.1.1.1.1      25MAR2019       644        42       SEVERE        Yes         1         No         6          1     
                                                    dcd B.2.2.3.1      25MAR2019       669       100        MILD         No          5         Yes        2          2     
———————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————


(1) Outcome: 1 = fatal; 2 = not recovered/not resolved; 3 = recovered/resolved;
    4 = recovered/resolved with sequelae; 5 = recovering/resolving; 6 = unknown.
(2) Action taken with study drug: 1 = dose increased; 2 = dose not changed;
    3 = dose reduced; 4 = drug interrupted; 5 = drug withdrawn; 6 = not applicable;
    7 = unknown.
(3) Reason classified as serious: 1 = resulted in death; 2 = life threatening;
    3 = required prolonged in patient hospitalization; 4 = disabling;
    5 = a congenital anomaly/birth defect in offspring of study subject;
    6 = does not meet any of the above serious criteria, but may jeopardize the subject,
    and may require medical or surgical intervention to prevent one of the outcomes listed above.
*  Study day derived from imputed onset date.
** Duration derived from imputed onset date and/or end date.

@Melkiades
Copy link
Contributor

@kathrinflunkert I probably need to see an example of real output to understand what is missing. I suspect that what you want is not really in scope with {rlistings} as it was defined only as a direct print of a data.frame. If you want to collapse two lines with a column that has "2, 3", I would try a manual update of these values. If that is what you want I could create a workaround with grouping and paste(). I think a custom function of that kind could be added for this specific cases to {rlistings} as a pre-processing tool

@kathrinflunkert
Copy link
Author

@Melkiades I agree that this is not a problem to be solved within the rlistings package, but this here is the Github section for tlg-catalog and the data preprocessing code for AEL03 on the tlg-catalog is leading to incorrect outputs as described above. That is why I as a user reported the issue here. I am not sure what is the best way to solve it. Adding the code to derive a new column that has a value of "2, 3" could be one way, maybe there is another way, I don't know.

@Melkiades
Copy link
Contributor

Yes, if it is an issue of pre-processing this is the right place. The values with multiple outcomes like "2, 3" need to be derived in pre-processing using {dplyr}

@yurovska
Copy link

Here is a solution:

test_data <- tibble(
  USUBJID = c("01", "02", "03"),
  AESDTH = c("N", "Y", "N"),
  AESLIFE = c("Y", "N", "Y"),
  AESHOSP = c("N", "Y", "Y"),
  AESDISAB = c("N", "N", "N"),
  AESCONG = c("Y", "N", "N"),
  AESMIE = c("N", "Y", "N")
)

test_data %>%
  mutate(
    SERREAS = purrr::pmap_chr(
      list(AESDTH, AESLIFE, AESHOSP, AESDISAB, AESCONG, AESMIE),
      ~ paste(which(c(...) == "Y"), collapse = ", ")
    )
  )
# A tibble: 3 × 8
USUBJID AESDTH AESLIFE AESHOSP AESDISAB AESCONG AESMIE SERREAS
<chr>   <chr>  <chr>   <chr>   <chr>    <chr>   <chr>  <chr>  
01      N      Y       N       N        Y       N      2, 5   
02      Y      N       Y       N        N       Y      1, 3, 6
03      N      Y       Y       N        N       N      2, 3   

@yurovska
Copy link

Another one (without {purrr}):

test_data %>%
  rowwise() %>%
  mutate(
    SERREAS = paste(
      which(
        c(AESDTH, AESLIFE, AESHOSP, AESDISAB, AESCONG, AESMIE) == "Y"
      ),
      collapse = ", "
    )
  ) %>%
  ungroup()

@Melkiades
Copy link
Contributor

Another one (without {purrr}):

test_data %>%
  rowwise() %>%
  mutate(
    SERREAS = paste(
      which(
        c(AESDTH, AESLIFE, AESHOSP, AESDISAB, AESCONG, AESMIE) == "Y"
      ),
      collapse = ", "
    )
  ) %>%
  ungroup()

Thanks so much!! I will update TLG-catalog with this if @kathrinflunkert is fine with this addition

@kathrinflunkert
Copy link
Author

Many thanks @yurovska!
Yes, please update the TLG-catalog accordingly @Melkiades. Thank you!

@Melkiades Melkiades self-assigned this Nov 12, 2024
Melkiades added a commit that referenced this issue Dec 2, 2024
Fixes #269

---------

Signed-off-by: Davide Garolini <[email protected]>
Signed-off-by: Davide Garolini <[email protected]>
Co-authored-by: Pawel Rucki <[email protected]>
Co-authored-by: Emily de la Rua <[email protected]>
Co-authored-by: Joe Zhu <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested sme
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants