Make pandas DataFrame from multiple STAR Log.final.out files.

    Parameters
    ----------
    fns : string
        List of paths to Log.final.out files.

    define_sample_name : function that takes string as input
        Function mapping filename to sample name. For instance, you may have the
        sample name in the path and use a regex to extract it.  The sample names
        will be used as the column names. If this is not provided, the columns
        will be named as the input files.

    Returns
    -------
    df : pandas.DataFrame
        DataFrame with info from log file.

def make_logs_df(fns, define_sample_name=None):
    """Make pandas DataFrame from multiple STAR Log.final.out files.

    Parameters
    ----------
    fns : string
        List of paths to Log.final.out files.

    define_sample_name : function that takes string as input
        Function mapping filename to sample name. For instance, you may have the
        sample name in the path and use a regex to extract it.  The sample names
        will be used as the column names. If this is not provided, the columns
        will be named as the input files.

    Returns
    -------
    df : pandas.DataFrame
        DataFrame with info from log file.

    """
    dfs = []
    for fn in fns:
        dfs.append(_read_log(fn, 
                             define_sample_name=define_sample_name))
    df = pd.concat(dfs,axis=1)
    df = df.T
    for label in [
            'Mapping speed, Million of reads per hour',
            'Number of input reads',
            'Average input read length',
            'Uniquely mapped reads number',
            'Average mapped length',
            'Number of splices: Total',
            'Number of splices: GT/AG',
            'Number of splices: GC/AG',
            'Number of splices: AT/AC',
            'Number of splices: Non-canonical',
            'Number of reads mapped to multiple loci',
            'Number of reads mapped to too many loci']:
        df[label] = df[label].astype(float)

    for label in [
        'Uniquely mapped reads %',
        'Mismatch rate per base, %',
        'Deletion rate per base',
        'Insertion rate per base',
        '% of reads mapped to multiple loci',
        '% of reads mapped to too many loci',
        '% of reads unmapped: too many mismatches',
        '% of reads unmapped: too short',
        '% of reads unmapped: other']:
        df[label] = df[label].apply(lambda x: x.strip('%')).astype(float)
    return df