If states are categories, you could map them to bins with bedmap.
Bins (using 1k-sized bins to demonstrate the process):
$ fetchChromSizes hg38 \
| awk -vOFS="\t" '{ print $1, "0", $2; } \
| grep -vE '*_*' \
| sort-bed - \
| bedops --chop 1000 - \
> hg38.1k.bed
Given a BED file of TSSs called tss.bed, you could get windows over the regions of interest via the following operations:
$ bedops -u --range -20000:10000 tss.bed | bedops --merge - | bedops --element-of 1 hg38.1k.bed - > hg38.1k.tssPad.bed
Say your categorical file is called states.bed. Given hg38.1k.tssPad.bed you could get the categorical labels via bedmap --echo-map-id:
$ bedmap --echo-map-id hg38.1k.tssPad.bed states.bed > states-over-bins.txt
Each line of states-over-bins.txt contains a semi-colon-delimited list of states that overlap that line's 1k bin.
This file can be brought into R for counting average state distribution for all states over 1k bins.