# Tag each unique combination of column values in DataFrames

**URL:** <https://discourse.julialang.org/t/tag-each-unique-combination-of-column-values-in-dataframes/76203>\
**Category:** Data\
**Tags:** dataframes\
**Created:** [February 11, 2022, 2:39am UTC](https://discourse.julialang.org/t/tag-each-unique-combination-of-column-values-in-dataframes/76203 "2022-02-11T02:39:25Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Gabriel\_Kreindler](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gabriel_kreindler/32/24961_2.png) [@Gabriel\_Kreindler](https://discourse.julialang.org/u/Gabriel_Kreindler)\
**Post date:** [February 11, 2022, 2:39am UTC](https://discourse.julialang.org/t/tag-each-unique-combination-of-column-values-in-dataframes/76203/1 "2022-02-11T02:39:25Z")

</div>

I have columns c1,c2, …, cN in a dataframe and I would like to create a column c\_new that takes a unique numeric value for each unique combination of values of c1,…, cN.

If there a function to achieve this?

(In Stata I would use `gen c_new = group(c1-cN)`)

My clunky code for two columns is:

```julia
function egen_group2(mydf::DataFrame, colname1::String, colname2::String, target_colname::String)
	#=
		creates a unique ID for each combination of colname1 and colname2
	=#

	egen_values_dict = Dict()
	col1 = Vector(mydf[:,colname1])
	col2 = Vector(mydf[:,colname2])

	n = length(mydf[:,colname1])
	@assert n == length(mydf[:,colname2])
	target_col = zeros(Int64, n)
	egen_idx_value = 1

        for i=1:n
		key = (col1[i], col2[i])
		if ~haskey(egen_values_dict, key)
			egen_values_dict[key] = egen_idx_value
			egen_idx_value += 1
		end
		target_col[i] = egen_values_dict[key]
	end

	mydf[:,target_colname] = target_col
end

```

---

<div class="post-metadata">

**Author:** ![pdeffebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pdeffebach/32/10320_2.png) [@pdeffebach](https://discourse.julialang.org/u/pdeffebach)\
**Post date:** [February 11, 2022, 2:48am UTC](https://discourse.julialang.org/t/tag-each-unique-combination-of-column-values-in-dataframes/76203/2 "2022-02-11T02:48:17Z")

</div>

Great question!

I’m not sure I have a great solution, and it looks others have requested the same based on [this github issue](https://github.com/JuliaData/DataFrames.jl/issues/2683).

The proposed solution by Bogumil is `groupindices)`

```julia
julia> df = DataFrame(a = rand(1:5, 100), b = rand(11:15, 100));

julia> gd = groupby(df, [:a, :b]);

julia> groupindices(gd)
100-element Vector{Union{Missing, Int64}}:
  7
 17
 17
 22
 17
  7
  7
  6
 11
 11
  ⋮
 12
 10
 14
 19
  1
  9
 20
 12
 18
  7

```

But as you can see there is still some discussion of adding a convenience function.

---

<div class="post-metadata">

**Author:** ![Gabriel\_Kreindler](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gabriel_kreindler/32/24961_2.png) [@Gabriel\_Kreindler](https://discourse.julialang.org/u/Gabriel_Kreindler)\
**Post date:** [February 11, 2022, 3:21am UTC](https://discourse.julialang.org/t/tag-each-unique-combination-of-column-values-in-dataframes/76203/3 "2022-02-11T03:21:59Z")

</div>

Nice! A bit more compactly as:

```julia
my_df.c_new = groupby(my_df, [:c1, :c2, :c3]) |> groupindices

```

---

<div class="post-metadata">

**Author:** ![bkamins](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bkamins/32/208538_2.png) [@bkamins](https://discourse.julialang.org/u/bkamins)\
**Post date:** [February 11, 2022, 6:36am UTC](https://discourse.julialang.org/t/tag-each-unique-combination-of-column-values-in-dataframes/76203/4 "2022-02-11T06:36:06Z")

</div>

One small comment `groupby(my_df, [:c1, :c2, :c3])` has an undefined order of the indices. If you pass `sort` kwarg to `groupby` you can control how the numbers are assigned.

---

<div class="post-metadata">

**Author:** ![rocco\_sprmnt21](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rocco_sprmnt21/32/20127_2.png) [@rocco\_sprmnt21](https://discourse.julialang.org/u/rocco_sprmnt21)\
**Post date:** [February 23, 2022, 2:59pm UTC](https://discourse.julialang.org/t/tag-each-unique-combination-of-column-values-in-dataframes/76203/5 "2022-02-23T14:59:07Z")

</div>

I probably didn’t get the sense of the request, but this isn’t right?

```julia
unique(string.(eachcol(df)...))

```

Now I think I understand better what the request was.  
I tried to read the docs related to the groupeddataframe module and I found this example that explains what has already been proposed.

```julia

df = DataFrame(a = rand(1:5, 100), b = rand(11:15, 100))
g=groupby(df,[:a,:b])
select(g, groupindices => :gid)

```

---

<div class="post-metadata">

**Author:** ![rocco\_sprmnt21](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rocco_sprmnt21/32/20127_2.png) [@rocco\_sprmnt21](https://discourse.julialang.org/u/rocco_sprmnt21)\
**Post date:** [February 23, 2022, 9:25pm UTC](https://discourse.julialang.org/t/tag-each-unique-combination-of-column-values-in-dataframes/76203/6 "2022-02-23T21:25:21Z")

</div>

I wanted to submit a deduction of the searched column made with functions of the Base module, even if a little naive, …

```julia
v=tuple.(eachcol(df)...)
sp=sortperm(v)
vsp=v[sp]
starts=[1;[i for i in 2:nrow(df) if vsp[i]!=vsp[i-1]];nrow(df)+1]
gidx=reduce(vcat,[fill(i,n) for (i,n) in enumerate(diff(starts))])
df.new_col=last.(sort(tuple.(sp,gidx), by=first))

```
