How to "label" DataFrame categorical column?

How can I rename the levels of a categorical column in a DataFrame? I tried this but it throws an error:

using DataFrames
using CategoricalArrays

df = DataFrame(x=[1, 2, 3])
df.x = categorical(df.x)
levels!(df.x, ["one", "two", "three"])

ERROR: LoadError: ArgumentError: cannot remove level 1 as it is used at position 1. Change the array element type to Union{Int64, Missing} using convert if you want to transform some levels to missing values.

You can do e.g. (to show the use of DataFramesMeta.jl):

julia> using DataFramesMeta

julia> @transform(df, :x = recode(:x, 1 => "one", 2 => "two", 3 => "tree"))
3Γ—1 DataFrame
 Row β”‚ x
     β”‚ Cat…
   1 β”‚ one
   2 β”‚ two
   3 β”‚ tree

the point is that you cannot replace integers with strings in place as it would change the element type of the container. You need to create a new recoded categorical vector.

If you want just to get the vector use:

julia> recode(df.x, 1 => "one", 2 => "two", 3 => "tree")
3-element CategoricalArray{String,1,UInt32}: