def agg_cause_specific_metrics(agg, metric, actual, predicted, weights=None):
    """Aggregate cause specific metrics into a single estimate

    It is useful to have a single performance metric at the individual-level.
    Some metrics only produce cause-specific estimates. These estimates can be
    aggregated in different ways to produce a single overall performance
    estimate.

    Args:
        agg (function): A function to aggregate across cause-specific estimates
            with the following sigature (sequence [, weights]) --> float where
            weights is a sequence with the same length as the number of actual
            prediction labels.
        metric (function): A function to compute cause specific metrics withthe
            following sigature: (label, pd.Series, pd.Series) --> float where
            label is a str or int value in the series.
        actual (pd.Series): true individual level classification
        predicted (pd.Series): individual level predictions
        weights (bool or sequence): use the true distribution as weights when
            aggregating across causes

    Returns:
        float

    Example:

    >>> agg_cause_specific_metrics(np.median, calc_ccc, actual, predicted)
    >>> agg_cause_specific_metrics(np.average, calc_ccc, actual, predicted,
                                   weights=True)
    """
    causes = actual.unique()
    if weights is True:
        csmf_true = (actual.value_counts() / len(actual)).loc[causes].values
        w = {'weights': csmf_true}
    elif weights:
        w = weights
    else:
        w = dict()
    return agg([metric(cause, actual, predicted) for cause in causes], **w)