Returns a boolean index of genes that have a peak nearby.

        Parameters
        ----------
        peaks : string or pybedtools.BedTool
            If string, then assume it's a filename to a BED/GFF/GTF file of
            intervals; otherwise use the pybedtools.BedTool object directly.

        transform_func : callable
            This function will be applied to each gene object returned by
            self.features().  Additional args and kwargs are passed to
            `transform_func`. For example, if you're looking for peaks within
            1kb upstream of TSSs, then pybedtools.featurefuncs.TSS would be
            a useful `transform_func`, and you could supply additional kwargs
            of `upstream=1000` and `downstream=0`.

            This function can return iterables of features, too. For example,
            you might want to look for peaks falling within the exons of
            a gene.  In this case, `transform_func` should return an iterable
            of pybedtools.Interval objects.  The only requirement is that the
            `name` field of any feature matches the index of the dataframe.

        intersect_kwargs : dict
            kwargs passed to pybedtools.BedTool.intersect.

        id_attribute : str
            The attribute in the GTF or GFF file that contains the id of the
            gene. For meaningful results to be returned, a gene's ID be also
            found in the index of the dataframe.

            For GFF files, typically you'd use `id_attribute="ID"`.  For GTF
            files, you'd typically use `id_attribute="gene_id"`.

def genes_with_peak(self, peaks, transform_func=None, split=False,
                        intersect_kwargs=None, id_attribute='ID', *args,
                        **kwargs):
        """
        Returns a boolean index of genes that have a peak nearby.

        Parameters
        ----------
        peaks : string or pybedtools.BedTool
            If string, then assume it's a filename to a BED/GFF/GTF file of
            intervals; otherwise use the pybedtools.BedTool object directly.

        transform_func : callable
            This function will be applied to each gene object returned by
            self.features().  Additional args and kwargs are passed to
            `transform_func`. For example, if you're looking for peaks within
            1kb upstream of TSSs, then pybedtools.featurefuncs.TSS would be
            a useful `transform_func`, and you could supply additional kwargs
            of `upstream=1000` and `downstream=0`.

            This function can return iterables of features, too. For example,
            you might want to look for peaks falling within the exons of
            a gene.  In this case, `transform_func` should return an iterable
            of pybedtools.Interval objects.  The only requirement is that the
            `name` field of any feature matches the index of the dataframe.

        intersect_kwargs : dict
            kwargs passed to pybedtools.BedTool.intersect.

        id_attribute : str
            The attribute in the GTF or GFF file that contains the id of the
            gene. For meaningful results to be returned, a gene's ID be also
            found in the index of the dataframe.

            For GFF files, typically you'd use `id_attribute="ID"`.  For GTF
            files, you'd typically use `id_attribute="gene_id"`.
        """
        def _transform_func(x):
            """
            In order to support transform funcs that return a single feature or
            an iterable of features, we need to wrap it
            """
            result = transform_func(x)
            if isinstance(result, pybedtools.Interval):
                result = [result]
            for i in result:
                if i:
                    yield result

        intersect_kwargs = intersect_kwargs or {}
        if not self._cached_features:
            self._cached_features = pybedtools\
                .BedTool(self.features())\
                .saveas()

        if transform_func:
            if split:
                features = self._cached_features\
                    .split(_transform_func, *args, **kwargs)
            else:
                features = self._cached_features\
                    .each(transform_func, *args, **kwargs)

        else:
            features = self._cached_features

        hits = list(set([i[id_attribute] for i in features.intersect(
            peaks, **intersect_kwargs)]))
        return self.data.index.isin(hits)