public static AssociativeArray2D survivalFunction ( FlatDataCollection flatDataCollection ) { AssociativeArray2D survivalFunction = new AssociativeArray2D ( ) ; //AssociativeArray2D is important to maintain the order of the first keys Queue < Double > censoredData = new PriorityQueue <> ( ) ; Queue < Double > uncensoredData = new PriorityQueue <> ( ) ; int n = flatDataCollection . size ( ) ; if ( n == 0 ) { throw new IllegalArgumentException ( "The provided collection can't be empty." ) ; } for ( Object value : flatDataCollection ) { String str = value . toString ( ) ; if ( str . endsWith ( CENSORED_NUMBER_POSTFIX ) ) { //censored internalData encoded as 4.3+ or -4.3+ censoredData . add ( Double . valueOf ( str . substring ( 0 , str . length ( ) - CENSORED_NUMBER_POSTFIX . length ( ) ) ) ) ; //remove the trailing char and convert it to double } else { //uncensored internalData uncensoredData . add ( TypeInference . toDouble ( value ) ) ; //convert it to double } } Double currentCensored = null ; Double currentUncensored = null ; int i = 1 ; double previousUncensoredValue = 1.0 ; double varianceDenominator = 0.0 ; do { if ( currentCensored == null ) { currentCensored = censoredData . poll ( ) ; } if ( currentUncensored == null ) { currentUncensored = uncensoredData . poll ( ) ; } boolean isCensored = false ; String key ; if ( currentUncensored == null ) { key = currentCensored . toString ( ) . concat ( CENSORED_NUMBER_POSTFIX ) ; currentCensored = null ; isCensored = true ; } else if ( currentCensored == null ) { key = currentUncensored . toString ( ) ; currentUncensored = null ; } else if ( currentCensored < currentUncensored ) { //NOT EQUAL! Uncensored internalData of the same value are always larger key = currentCensored . toString ( ) . concat ( CENSORED_NUMBER_POSTFIX ) ; currentCensored = null ; isCensored = true ; } else { key = currentUncensored . toString ( ) ; currentUncensored = null ; } Integer previousMi = ( Integer ) survivalFunction . get2d ( key , "mi" ) ; if ( previousMi == null ) { previousMi = 0 ; } //in case of ties the last value will overwrite the previous. Thus we make automatically the tie correction survivalFunction . put2d ( key , "i" , i ) ; survivalFunction . put2d ( key , "mi" , previousMi + 1 ) ; if ( isCensored == false ) { survivalFunction . put2d ( key , "r" , i ) ; double Sti = ( n - i ) / ( n - i + 1.0 ) * previousUncensoredValue ; if ( n - i > 0 ) { varianceDenominator += 1.0 / ( ( n - i ) * ( n - i + 1.0 ) ) ; } survivalFunction . put2d ( key , "Sti" , Sti ) ; survivalFunction . put2d ( key , "varianceSti" , Sti * Sti * varianceDenominator ) ; previousUncensoredValue = Sti ; } ++ i ; } while ( currentCensored != null || currentUncensored != null || ! censoredData . isEmpty ( ) || ! uncensoredData . isEmpty ( ) ) ; //censoredData=null; //uncensoredData=null; return survivalFunction ; }
Calculates the survivalFunction by processing the flatDataCollection with the censored internalData . The flatDataCollection contains numbers in string format . The Censored entries contain a + symbol at the end of the number .