def extract_outcomes(self, simulated_patients): """ extracts outcomes of a simulated cohort :param simulated_patients: a list of simulated patients""" # record survival time and time until AIDS for patient in simulated_patients: # survival time if patient.stateMonitor.survivalTime is not None: self.survivalTimes.append(patient.stateMonitor.survivalTime) # time until AIDS if patient.stateMonitor.timeToAIDS is not None: self.timesToAIDS.append(patient.stateMonitor.timeToAIDS) # discounted cost and discounted utility self.costs.append( patient.stateMonitor.costUtilityMonitor.totalDiscountedCost) self.utilities.append( patient.stateMonitor.costUtilityMonitor.totalDiscountedUtility) # summary statistics self.statSurvivalTime = Stat.SummaryStat(name='Survival time', data=self.survivalTimes) self.statTimeToAIDS = Stat.SummaryStat(name='Time until AIDS', data=self.timesToAIDS) self.statCost = Stat.SummaryStat(name='Discounted cost', data=self.costs) self.statUtility = Stat.SummaryStat(name='Discounted utility', data=self.utilities) # survival curve self.nLivingPatients = Path.PrevalencePathBatchUpdate( name='# of living patients', initial_size=len(simulated_patients), times_of_changes=self.survivalTimes, increments=[-1] * len(self.survivalTimes))
def if_acceptable(self, scenario): """ :returns True if this scenario meets the conditions to be on this series """ if self.scenarioNames is not None: # if the name of this scenario is included if scenario.name in self.scenarioNames: return True else: for condition in self.varConditions: if condition.values is None: if scenario.variables[condition.varName] < condition.min \ or scenario.variables[condition.varName] > condition.max: return False else: if not (scenario.variables[condition.varName] in condition.values): return False for condition in self.outcomeConditions: if condition.values is None: # mean of this outcome mean = Stat.SummaryStat( name=condition.outcomeName, data=scenario.outcomes[ condition.outcomeName]).get_mean() if mean < condition.min or mean > condition.max: return False return True
def calculate_summary_stats(self): """ calculate the summary statistics """ # summary statistics of mean survival time self.statMeanSurvivalTime = Stat.SummaryStat( name='Average survival time', data=self.meanSurvivalTimes) # summary statistics of mean time to AIDS self.statMeanTimeToAIDS = Stat.SummaryStat(name='Average time to AIDS', data=self.meanTimeToAIDS) # summary statistics of mean cost self.statMeanCost = Stat.SummaryStat(name='Average cost', data=self.meanCosts) # summary statistics of mean QALY self.statMeanQALY = Stat.SummaryStat(name='Average QALY', data=self.meanQALYs)
def calculate_cohort_outcomes(self, initial_pop_size): """ calculates the cohort outcomes :param initial_pop_size: initial population size """ self.statSurvivalTime = Stat.SummaryStat(name='Survival Time', data=self.survivalTimes) self.statCost = Stat.SummaryStat(name='Discounted cost', data=self.costs) self.statUtility = Stat.SummaryStat(name='Discounted utility', data=self.utilities) self.statNumStrokes = Stat.SummaryStat(name='Total Number of Strokes', data=self.nStrokes) self.nLivingPatients = Path.PrevalencePathBatchUpdate( name='# of living patients', initial_size=initial_pop_size, times_of_changes=self.survivalTimes, increments=[-1] * len(self.survivalTimes))
def simulate(self, n): for i in range(n): model = Model(decision_rule=self.decisionRule, cost_sigma=self.costSigma, action_cost=self.actionCost) model.simulate(itr=i) self.cumCosts.append(sum(model.seqCosts)) self.statCost = S.SummaryStat(data=self.cumCosts)
def get_cohort_PI_survival(self, cohort_index, alpha): """ :returns: the prediction interval of the survival time for a specified cohort :param cohort_index: integer over [0, 1, ...] corresponding to the 1st, 2ndm ... simulated cohort :param alpha: significance level """ stat = Stat.SummaryStat(name='Summary statistics', data=self.survivalTimes[cohort_index]) return stat.get_PI(alpha=alpha)
def get_mean_interval(self, parameter_name, deci=0, form=None): # print the ratio estimate and credible interval sum_stat = Stat.SummaryStat('', self.dictOfParamValues[parameter_name]) if form is None: return sum_stat.get_mean(), sum_stat.get_PI(alpha=0.05) else: return sum_stat.get_formatted_mean_and_interval( interval_type='p', alpha=0.05, deci=deci, form=form)
def get_ratio_mean_interval(self, numerator_par_name, denominator_par_names, deci=0, form=None): # print the ratio estimate and credible interval sum_stat = Stat.SummaryStat('', self.__calculate_ratio_obss(numerator_par_name, denominator_par_names)) if form is None: return sum_stat.get_mean(), sum_stat.get_PI(alpha=0.05) else: return sum_stat.get_formatted_mean_and_interval( interval_type='p', alpha=0.05, deci=deci, form=form)
def calculate_summary_stats(self): """ calculate the summary statistics """ # calculate average patient survival time for all simulated cohorts for obs_set in self.survivalTimes: self.meanSurvivalTimes.append(sum(obs_set) / len(obs_set)) # summary statistics of mean survival time self.statMeanSurvivalTime = Stat.SummaryStat( name='Mean survival time', data=self.meanSurvivalTimes)
def get_mean_interval(self, scenario_name, outcome_name, interval_type='c', deci=0, form=None): """ :return: mean and percentile interval of the selected outcome for the selected scenario """ stat = Stat.SummaryStat( name='', data=self.scenarios[scenario_name].outcomes[outcome_name]) return Support.get_mean_interval(stat, interval_type, deci, form)
def get_mortality_estimate_credible_interval(self, alpha): """ :param alpha: the significance level :returns tuple (mean, [lower, upper]) of the posterior distribution""" # calculate the credible interval sum_stat = Stat.SummaryStat(name='Posterior samples', data=self.resampledMortalityProb) estimate = sum_stat.get_mean() # estimated mortality probability credible_interval = sum_stat.get_PI(alpha=alpha) # credible interval return estimate, credible_interval
def utility_sample_stat(utility, d_cost_samples, d_effect_samples, wtp_random_variate, n_samples, rnd): discrete_rnd = RVG.UniformDiscrete(l=0, u=len(d_cost_samples) - 1) samples = [] for i in range(n_samples): j = discrete_rnd.sample(rnd) u = utility(d_effect=d_effect_samples[j], d_cost=d_cost_samples[j]) w = wtp_random_variate.sample(rnd) samples.append(u(w)) return Stat.SummaryStat(name='', data=samples)
def print_outcomes(simulated_cohort, strategy_name): """ prints the outcomes of a simulated cohort under steady state :param simulated_cohort: a simulated cohort :param strategy_name: the name of the selected therapy """ # create a summary statistics survival_time_stat = Stat.SummaryStat( name='Survival time statistics', data=simulated_cohort.cohortOutcomes.survivalTimes) # get mean and confidence confidence interval mean = survival_time_stat.get_mean() conf_int = survival_time_stat.get_t_CI(alpha=D.ALPHA) # print survival time statistics print(strategy_name) print( " Estimate of mean survival time (years) and {:.{prec}%} confidence interval:" .format(1 - D.ALPHA, prec=0), mean, conf_int)
def print_outcomes(multi_cohort, strategy_name): """ prints the outcomes of a simulated cohort under steady state :param multi_cohort: output of a simulated cohort :param strategy_name: the name of the selected therapy """ # create a summary statistics survival_time_stat = Stat.SummaryStat( name='Survival time statistics', data=multi_cohort.multiCohortOutcomes.meanSurvivalTimes) # get mean and t-based confidence interval mean = survival_time_stat.get_mean() pred_int = survival_time_stat.get_PI(alpha=D.ALPHA) # print survival time statistics print(strategy_name) print( " Estimate of mean survival time (years) and {:.{prec}%} prediction interval:" .format(1 - D.ALPHA, prec=0), mean, pred_int)
def get_means_and_intervals(self, significance_level=0.05, sig_digits=3, param_names=None, prior_info_csv_file=None): """ :param significance_level: (float) significant level to calculate confidence or credible intervals :param sig_digits: (int) number of significant digits :param param_names: (list) of parameter names :param prior_info_csv_file: (string) :return: """ results = [] # list of parameter estimates and credible intervals # read information about prior distributions dict_of_priors = None if prior_info_csv_file is not None: dict_of_priors = self.get_dict_of_priors(prior_info_csv_file=prior_info_csv_file) # if parameter names are not specified, include all parameters if param_names is None: param_names = self.get_all_parameter_names() # for each parameter get mean and intervals for par_name in param_names: # get values for this parameter par_values = self.dictOfParamValues[par_name] # get info of this parameter title, multiplier, x_range, decimal, form = self.get_title_multiplier_x_range_decimal_format( par_name=par_name, dict_of_priors=dict_of_priors) # summary statistics sum_stat = Stat.SummaryStat(name=par_name, data=par_values) mean_PI_text = sum_stat.get_formatted_mean_and_interval( interval_type='p', alpha=significance_level, deci=decimal, sig_digits=sig_digits, form=form, multiplier=multiplier) results.append( [par_name, mean_PI_text]) return results
def get_mean_PI(self, time_index, alpha, multiplier=1, deci=0, format=None): """ :param format: additional formatting instruction. Use ',' to format as number, '%' to format as percentage, and '$' to format as currency :return: the mean and percentile interval of observations at the specified time index formatted as instructed """ # find the estimate and percentile interval stat = Stat.SummaryStat('', self.get_obss(time_index) * multiplier) estimate, pi = stat.get_mean(), stat.get_PI(alpha) if format is None: return estimate, pi else: return F.format_estimate_interval(estimate=estimate, interval=pi, deci=deci, format=format)
def populate_sets_of_scenarios(list_of_scenario_sets, save_cea_results=False, colors_of_scenarios=None, interval_type='n', effect_multiplier=1, cost_multiplier=1, switch_cost_effect_on_figure=False, wtp_range=None): """ :param list_of_scenario_sets: (list) of sets of scenarios :param save_cea_results: set it to True if the CE table should be generated :param colors_of_scenarios: (dictionary) of colors for scenarios :param interval_type: select from Econ.Interval (no interval, CI, or PI) :param effect_multiplier: :param cost_multiplier: :param switch_cost_effect_on_figure: displays cost on the x-axis and effect on the y-axis :param wtp_range: for net monetary benefit analysis """ # populate series to display on the cost-effectiveness plane for i, scenario_set in enumerate(list_of_scenario_sets): if scenario_set.ifPopulated: continue # create the base strategy scn = scenario_set.scenarioDF.scenarios['Base'] base_strategy = Econ.Strategy( name='Base', label='Base', cost_obs=scn.outcomes[COST_MEASURE], effect_obs=scn.outcomes[HEALTH_MEASURE], color=None if colors_of_scenarios is None else colors_of_scenarios[0]) # add base scenario_set.strategies = [base_strategy] # add other scenarios i = 0 for key, scenario in scenario_set.scenarioDF.scenarios.items(): # add only non-Base strategies that can be on this series if scenario.name != 'Base' and scenario_set.if_acceptable( scenario): # find labels of each strategy label_list = [] for varCon in scenario_set.varConditions: if varCon.ifIncludedInLabel: # value of this variable value = scenario.variables[varCon.varName] # if there is not label rules if varCon.labelRules is None: if varCon.labelFormat == '': label_list.append(str(value) + ',') else: label_list.append( varCon.labelFormat.format(value) + ', ') else: label = varCon.get_label(value) if label == '': pass else: label_list.append(label + ', ') for outcomeCon in scenario_set.outcomeConditions: if outcomeCon.ifIncludedInLabel: # value of this variable value = Stat.SummaryStat( name=outcomeCon.outcomeName, data=scenario.outcomes[ outcomeCon.outcomeName]).get_mean() # if there is not label rules if outcomeCon.labelRules is None: if outcomeCon.labelFormat == '': label_list.append(str(value) + ',') else: label_list.append( outcomeCon.labelFormat.format(value) + ', ') else: label = outcomeCon.get_label(value) if label == '': pass else: label_list.append(label + ', ') label = ''.join(str(x) for x in label_list) if len(label) > 0: if label[-1] == ' ' or label[-1] == ',': label = label[:-1] if label[-1] == ' ' or label[-1] == ',': label = label[:-1] # legends scenario_set.legend.append(label) # color of this strategy color = None if colors_of_scenarios is not None: color = colors_of_scenarios[i + 1] if scenario_set.xyLabelsProvided: label = scenario_set.xyLabels[i] scenario_set.strategies.append( Econ.Strategy( name=scenario.name, label=label, cost_obs=scenario.outcomes[COST_MEASURE], effect_obs=scenario.outcomes[HEALTH_MEASURE], color=color)) i += 1 # do CEA on this series scenario_set.build_CE_curve( save_cea_results=save_cea_results, interval_type=interval_type, effect_multiplier=effect_multiplier, cost_multiplier=cost_multiplier, switch_cost_effect_on_figure=switch_cost_effect_on_figure, wtp_range=wtp_range) scenario_set.ifPopulated = True
import SimPy.Plots.Histogram as Hist import SimPy.Plots.ProbDist as Plot import SimPy.RandomVariateGenerators as RVGs import SimPy.Statistics as Stat # read weekly number of drinks cols = IO.read_csv_cols(file_name='dataNumOfDrinks.csv', n_cols=1, if_ignore_first_row=True, if_convert_float=True) # make a histogram Hist.plot_histogram(data=cols[0], title='Weekly Number of Drinks', bin_width=1) # mean and standard deviation stat = Stat.SummaryStat(name='Weekly number of drinks', data=cols[0]) print('Mean = ', stat.get_mean()) print('StDev = ', stat.get_stdev()) # fit a Poisson distribution fit_results = RVGs.Poisson.fit_ml(data=cols[0]) print('Fitting a Poisson distribution:', fit_results) # plot the fitted Poisson distribution Plot.plot_poisson_fit(data=cols[0], fit_results=fit_results, x_label='Weekly number of drinks', x_range=(0, 40), bin_width=1) # fit a gamma-Poisson distribution
def calculate_means_and_intervals(self, poster_file='ParameterEstimates.csv', significance_level=0.05, deci=3, ids=None, csv_file_name_prior=None): """ calculate the mean and credible intervals of parameters specified by ids :param poster_file: csv file where the posterior ranges should be stored :param significance_level: :param deci: :param ids: :param csv_file_name_prior: (string) filename where parameter prior ranges are located :return: """ # read prior distributions priors = None if csv_file_name_prior is not None: priors = IO.read_csv_rows(file_name=csv_file_name_prior, if_ignore_first_row=True, delimiter=',', if_convert_float=True) results = [] # list of parameter estimates and credible intervals par_id = 0 for key, value in self.dictOfParams.items(): # skip these columns if key in ['Simulation Replication', 'Random Seed']: continue # if estimates and credible intervals should be calculated for this parameter if_record = False if ids is None: if_record = True elif par_id in ids: if_record = True # record the calculated estimate and credible interval if if_record: if priors is None: decimal = deci form = '' multip = 1 else: decimal = priors[par_id][Column.DECI.value] decimal = 0 if decimal is None else decimal form = priors[par_id][Column.FORMAT.value] multip = priors[par_id][Column.MULTIPLIER.value] if multip is None: data = value else: multip = float(multip) data = [multip * x for x in value] sum_stat = Stat.SummaryStat(name=key, data=data) mean_text = Format.format_number(number=sum_stat.get_mean(), deci=decimal, format=form) PI_text = Format.format_interval( interval=sum_stat.get_PI(significance_level), deci=decimal, format=form) results.append([par_id, key, mean_text, PI_text]) # next parameter par_id += 1 # write parameter estimates and credible intervals IO.write_csv(rows=results, file_name=poster_file)
def mytest_summary_stat(data): # define a summary statistics sum_stat = Stat.SummaryStat(data=data, name='Test summary statistics',) print('Testing summary statistics:') print_results(sum_stat)
SIM_POP_SIZE = 1000 # population size of the simulated cohort # create a cohort myCohort = Cls.Cohort(id=1, pop_size=SIM_POP_SIZE, mortality_prob=MORTALITY_PROB) # simulate the cohort over the specified time steps myCohort.simulate(n_time_steps=TIME_STEPS) # plot the sample path Path.plot_sample_path(sample_path=myCohort.cohortOutcomes.nLivingPatients, title='Survival Curve', x_label='Time-Step (Year)', y_label='Number Survived') # plot the histogram Hist.plot_histogram(data=myCohort.cohortOutcomes.survivalTimes, title='Histogram of Patient Survival Time', x_label='Survival Time (Year)', y_label='Count') # create a summary statistics for observations of survival times survivalTimeStat = Stat.SummaryStat(name='Summary statistics of survival time', data=myCohort.cohortOutcomes.survivalTimes) # print the summary statistics print('Mean survival time (years):', survivalTimeStat.get_mean()) print('95% confidence interval of mean survival time (years):', survivalTimeStat.get_t_CI(alpha=0.05))