For future reference, please provide what the correct output should be instead of just an example output.
You can perform a group by, take the unique States for each ID, then take the value counts of that
combinations = df.group_by('id').agg(pl.col('state').unique())
counts = combinations.select(pl.col('state').value_counts().alias('counts'))
print(counts.unnest('counts'))
assert (counts.select(pl.col('counts').struct.field('count').sum()) == df.n_unique('id')).item()
# Alternatively, as a single expression:
print(df.select(
pl.col('state').unique().implode()
.over('id', mapping_strategy='explode')
.value_counts()
.struct.unnest()
))