# Categorical to Integer values?

**URL:** <https://discourse.julialang.org/t/categorical-to-integer-values/24588>\
**Category:** New to Julia\
**Created:** [May 24, 2019, 9:49pm UTC](https://discourse.julialang.org/t/categorical-to-integer-values/24588 "2019-05-24T21:49:01Z")\
**Posts on this page:** 17\
**Page:** 1

<div class="post-metadata">

**Author:** ![dlakelan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dlakelan/32/8491_2.png) [@dlakelan](https://discourse.julialang.org/u/dlakelan)\
**Post date:** [May 24, 2019, 9:49pm UTC](https://discourse.julialang.org/t/categorical-to-integer-values/24588/1 "2019-05-24T21:49:01Z")

</div>

If I have a DataFrame with a categorical column, how can I convert it to integers, like in R if foo is a data table with a categorical variable bar, you would do as.numeric(foo$bar)

I plan to index into an array based on which category things are in… and want to work with integers, not names of integers.

---

<div class="post-metadata">

**Author:** ![dlakelan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dlakelan/32/8491_2.png) [@dlakelan](https://discourse.julialang.org/u/dlakelan)\
**Post date:** [May 24, 2019, 10:24pm UTC](https://discourse.julialang.org/t/categorical-to-integer-values/24588/2 "2019-05-24T22:24:57Z")

</div>

I see that I can access the internal “refs” field and this is the number that indexes the levels… but is this the “official” way?

---

<div class="post-metadata">

**Author:** ![nalimilan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nalimilan/32/147_2.png) [@nalimilan](https://discourse.julialang.org/u/nalimilan)\
**Post date:** [June 1, 2019, 9:09pm UTC](https://discourse.julialang.org/t/categorical-to-integer-values/24588/3 "2019-06-01T21:09:22Z")

</div>

We should definitely add a public function to get integer codes. Waiting for it you can access the `refs` field, but note that its values correspond to the order in `index(x.pool)`, not to those in `levels(x)`. See the warning at [Implementation details · CategoricalArrays](https://juliadata.github.io/CategoricalArrays.jl/latest/implementation.html).

---

<div class="post-metadata">

**Author:** ![dlakelan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dlakelan/32/8491_2.png) [@dlakelan](https://discourse.julialang.org/u/dlakelan)\
**Post date:** [June 2, 2019, 6:51pm UTC](https://discourse.julialang.org/t/categorical-to-integer-values/24588/4 "2019-06-02T18:51:09Z")

</div>

Thanks for pointing that out! I think ideally you’d just create a constructor for Int… and it’d return the index into the levels… so something like this?

```julia
function Int(a::CategoricalArray)
   map(x -> Int(x),CategoricalArrays.order(a.pool)[a.refs]);
end

```

Similarly for explicit UInt32 and UInt64 and etc.

WHOOPS, I’m obviously new to Julia, of course you’re going to return an Array{Int} so I guess you’d want

```julia
function Array{Int}(a::...

```

---

<div class="post-metadata">

**Author:** ![bernhard](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bernhard/32/2619_2.png) [@bernhard](https://discourse.julialang.org/u/bernhard)\
**Post date:** [June 3, 2019, 6:43am UTC](https://discourse.julialang.org/t/categorical-to-integer-values/24588/5 "2019-06-03T06:43:17Z")

</div>

I am not sure if your function definition is a good idea. It seems you might be overloading `Int`. How about just converting the type (to whatever type you want):

```julia
using RDatasets
iris = dataset("datasets", "iris")

v=iris[:Species]

function get_indices(v)
    return CategoricalArrays.order(v.pool)[v.refs]
end
    
refs=get_indices(iris[:Species])
refs2=convert(Vector{Int},refs)

```

---

<div class="post-metadata">

**Author:** ![dlakelan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dlakelan/32/8491_2.png) [@dlakelan](https://discourse.julialang.org/u/dlakelan)\
**Post date:** [June 3, 2019, 11:26am UTC](https://discourse.julialang.org/t/categorical-to-integer-values/24588/6 "2019-06-03T11:26:35Z")

</div>

I’m just learning Julia so I don’t know all the idioms but that seems like a bunch of work and it does exactly the same thing right? namely it gives you an array of ints?

what is the reason not to just construct an Array{Int} ?

indeed the Julia manual page 177 discusses convert vs constructor and clearly says conversion is for different representation of the same thing… here we are constructing an array of ints from a categorical representation of strings, it seems like a constructor is exactly what we want.

---

<div class="post-metadata">

**Author:** ![bernhard](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bernhard/32/2619_2.png) [@bernhard](https://discourse.julialang.org/u/bernhard)\
**Post date:** [June 3, 2019, 12:35pm UTC](https://discourse.julialang.org/t/categorical-to-integer-values/24588/7 "2019-06-03T12:35:55Z")

</div>

As I said above: “I am not sure”. Feel free to use whatever approach works for you.

---

<div class="post-metadata">

**Author:** ![dlakelan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dlakelan/32/8491_2.png) [@dlakelan](https://discourse.julialang.org/u/dlakelan)\
**Post date:** [June 3, 2019, 1:07pm UTC](https://discourse.julialang.org/t/categorical-to-integer-values/24588/8 "2019-06-03T13:07:10Z")

</div>

I guess the question is, is there a good abstraction here that should be built-in to the CategoricalArrays package? It seems to me like an Array{Int} constructor is something the package should provide and it should give integers that index into the levels.

---

<div class="post-metadata">

**Author:** ![nalimilan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nalimilan/32/147_2.png) [@nalimilan](https://discourse.julialang.org/u/nalimilan)\
**Post date:** [June 3, 2019, 9:11pm UTC](https://discourse.julialang.org/t/categorical-to-integer-values/24588/9 "2019-06-03T21:11:11Z")

</div>

Yes, it could be confusing to use `Int` since e.g. a categorical array with levels `["3", "2", "1"]` or even worse `[3, 2, 1]` would return values which do not correspond to the levels, but to their order. So calling `Int.(x)` on the array could give unexpected results. Probably better introduce a dedicated function, but I’m not sure what name would be appropriate.

---

<div class="post-metadata">

**Author:** ![dlakelan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dlakelan/32/8491_2.png) [@dlakelan](https://discourse.julialang.org/u/dlakelan)\
**Post date:** [June 3, 2019, 9:25pm UTC](https://discourse.julialang.org/t/categorical-to-integer-values/24588/10 "2019-06-03T21:25:29Z")

</div>

I’ll buy that, so how about `level_codes` for a function name.

---

<div class="post-metadata">

**Author:** ![Nosferican](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nosferican/32/9275_2.png) [@Nosferican](https://discourse.julialang.org/u/Nosferican)\
**Post date:** [June 5, 2019, 9:22pm UTC](https://discourse.julialang.org/t/categorical-to-integer-values/24588/11 "2019-06-05T21:22:33Z")

</div>

I am not opposed to something like `level_codes` and probably first best. I still think something like `convert(Int, x)` could/should return the reference position in the pool.

---

<div class="post-metadata">

**Author:** ![eleuven](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/eleuven/32/8768_2.png) [@eleuven](https://discourse.julialang.org/u/eleuven)\
**Post date:** [June 6, 2019, 8:38am UTC](https://discourse.julialang.org/t/categorical-to-integer-values/24588/12 "2019-06-06T08:38:17Z")

</div>

maybe `categories` is a better name given that these are categorical arrays

---

<div class="post-metadata">

**Author:** ![dlakelan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dlakelan/32/8491_2.png) [@dlakelan](https://discourse.julialang.org/u/dlakelan)\
**Post date:** [June 6, 2019, 11:25am UTC](https://discourse.julialang.org/t/categorical-to-integer-values/24588/13 "2019-06-06T11:25:36Z")

</div>

well I’d expect categories to return what levels returns, basically the category names… but since we have levels already and the R equivalent is levels… it seems `level_codes` makes good sense, or `level_numbers` or `level_indices` of those I think I prefer codes because it’s easy to say and type

---

<div class="post-metadata">

**Author:** ![eleuven](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/eleuven/32/8768_2.png) [@eleuven](https://discourse.julialang.org/u/eleuven)\
**Post date:** [June 6, 2019, 11:57am UTC](https://discourse.julialang.org/t/categorical-to-integer-values/24588/14 "2019-06-06T11:57:50Z")

</div>

given that `levels` is there, `levels_indices` seems most explicit and unambiguous (since a level can also be a code or a number)

that said, i feel that `levels` is a bit of a misnomer since it suggests something ordinal and not categorical as opposed to, say, `values` or `categories`…

---

<div class="post-metadata">

**Author:** ![dlakelan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dlakelan/32/8491_2.png) [@dlakelan](https://discourse.julialang.org/u/dlakelan)\
**Post date:** [June 6, 2019, 12:15pm UTC](https://discourse.julialang.org/t/categorical-to-integer-values/24588/15 "2019-06-06T12:15:20Z")

</div>

the terminology is traditional and well known in statistics where categories are called factors and the levels of the factors is standard terminology, so I guess it depends on background as to which is more intuitive

---

<div class="post-metadata">

**Author:** ![eleuven](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/eleuven/32/8768_2.png) [@eleuven](https://discourse.julialang.org/u/eleuven)\
**Post date:** [June 6, 2019, 4:24pm UTC](https://discourse.julialang.org/t/categorical-to-integer-values/24588/16 "2019-06-06T16:24:33Z")

</div>

since the package is called `CategoricalArrays.jl` my brain was just primed for `categories`

---

<div class="post-metadata">

**Author:** ![Ramipo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ramipo/32/23423_2.png) [@Ramipo](https://discourse.julialang.org/u/Ramipo)\
**Post date:** [March 18, 2022, 11:53pm UTC](https://discourse.julialang.org/t/categorical-to-integer-values/24588/17 "2022-03-18T23:53:18Z")

</div>

I changed the type of categorical variables in columns “a” and “b” of a dataframe (df) by using the following code

```julia
df[:a]=Vector{Union{Float64}}(df[:a])
df[:b]=Vector{Union{Int, missing}}(df[:b])

```

The solution in the following Youtube video  
[Dataframe tutorial - categorical variables](https://youtu.be/0-Xsts_s5Wc?t=5030)
