A fun little two liner without any additional packages:
julia> uvals = sort(unique([df.x; df.y]))
3-element Vector{Symbol}:
:a
:b
:c
ulia> leftjoin(leftjoin(df, DataFrame(x = uvals, new_x = 1:length(uvals)), on = :x), DataFrame(y = uvals, new_y = 1:length(uvals)), on = :y)
5×4 DataFrame
Row │ x y new_x new_y
│ Symbol Symbol Int64? Int64?
─────┼────────────────────────────────
1 │ a b 1 2
2 │ a b 1 2
3 │ b c 2 3
4 │ c a 3 1
5 │ c c 3 3