Friday, June 09, 2023

replicate p value boundaries in KN604 with rpact

 KN604 final OS results were published in details. Here is the rpact code that replicates the p values boundaries, following the tutorial.




get_ai <- function( total_n, enroll_time, peak_time){
    p_n <- round(total_n / ( (enroll_time - peak_time) /2 + peak_time), 0) # the number of enrollment at peak

    c( seq(1, p_n, length.out = floor(enroll_time) - floor(peak_time)) , rep( p_n,  floor(peak_time) )) # enrollment intensity
  
}
       
ai <- get_ai ( 453,  14.5, 14.5 - 13) # enrollment pattern does not affect power or type 1 error and only affects timeline for TTE analysis
                          
#===== planned PFS
plan_pfs <-  getDesignGroupSequential(
    sided = 1, alpha = 0.006, 
    informationRates = c(332,387)/387, 
    typeOfDesign = "asOF"
)

x1 <- getPowerSurvival(plan_pfs,
    lambda1 = log(2)/4.3 *.65 , lambda2 = log(2)/4.3 ,
    dropoutRate1 = 0.01, dropoutRate2 = 0.01, dropoutTime = 1,
    accrualTime = 0:13, accrualIntensity  = ai, maxNumberOfSubjects = 453, maxNumberOfEvents = 396, directionUpper = F  )
 summary(x1) 
#====== planned OS
 
 plan_Os <-  getDesignGroupSequential(
    sided = 1, alpha = 0.019,
    informationRates = c(175,224,294)/294, 
    typeOfDesign = "asOF"
)
 
x2 <- getPowerSurvival(plan_Os,
    lambda1 = log(2)/10 * .65 , lambda2 =  log(2) / 10  ,
    dropoutRate1 = 0.01, dropoutRate2 = 0.01, dropoutTime = 1,
    accrualTime = 0:13, accrualIntensity  = ai, maxNumberOfSubjects = 453, maxNumberOfEvents = 294, directionUpper = F  )
 summary(x2) 
 
 
 #==== actual final OS, where PFS becomes sigificant at IA2
 
 designUpdate2 <- getDesignGroupSequential(
    sided = 1, alpha = 0.019 + 0.006, beta = 0.06,
    informationRates = c(182, 274,294)/294, typeOfDesign = "asOF"
)
 
 
 designUpdate3 <- getDesignGroupSequential(
    sided = 1, alpha = 0.025, beta = 0.06,
    informationRates = c(182, 274, 357)/357,
    typeOfDesign = "asUser",
    userAlphaSpending = designUpdate2$alphaSpent
)
 
 x3 <- getPowerSurvival(designUpdate3,
    lambda1 = log(2)/10 * 0.65 , lambda2 =  log(2) / 10 ,
    dropoutRate1 = 0.01, dropoutRate2 = 0.01, dropoutTime = 1,
    accrualTime = 0:13, accrualIntensity  = ai, maxNumberOfSubjects = 453, maxNumberOfEvents = 357, directionUpper = F  )
 summary(x3) 

No comments: