# Vcat DataFrame columns based on multiple columns in Julia

**URL:** <https://discourse.julialang.org/t/vcat-dataframe-columns-based-on-multiple-columns-in-julia/102932>\
**Category:** General Usage\
**Tags:** dataframes\
**Created:** [August 18, 2023, 7:09am UTC](https://discourse.julialang.org/t/vcat-dataframe-columns-based-on-multiple-columns-in-julia/102932 "2023-08-18T07:09:48Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Mark01](https://avatars.discourse-cdn.com/v4/letter/m/f475e1/32.png) [@Mark01](https://discourse.julialang.org/u/Mark01)\
**Post date:** [August 18, 2023, 7:09am UTC](https://discourse.julialang.org/t/vcat-dataframe-columns-based-on-multiple-columns-in-julia/102932/1 "2023-08-18T07:09:48Z")

</div>

I have 3 DataFrames, each containing 3 columns: A, B, and C.

```julia
using DataFrames    
common_data = Dict("A" => [1, 2, 3], "B" => [10, 20, 30])
df1 = DataFrame(merge(common_data, Dict("C" => [100, 200, 300])))
df2 = DataFrame(merge(common_data, Dict("C" => [400, 500, 600])))
df3 = DataFrame(merge(common_data, Dict("C" => [700, 800, 900])))

```

I consider columns A and B as indices and want to perform an inner join on 3 DataFrames based on column C. This should be done only when the values in columns A and B of each DataFrame are the same. The column of the final output should be `[A,B,C_df1,C_df2,C_df3]` . How can I achieve this?

---

<div class="post-metadata">

**Author:** ![Rudi79](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rudi79/32/3884_2.png) [@Rudi79](https://discourse.julialang.org/u/Rudi79)\
**Post date:** [August 18, 2023, 9:03am UTC](https://discourse.julialang.org/t/vcat-dataframe-columns-based-on-multiple-columns-in-julia/102932/2 "2023-08-18T09:03:47Z")

</div>

> [@Mark01](#):
>
> ```julia
> using DataFrames    
> common_data = Dict("A" => [1, 2, 3], "B" => [10, 20, 30])
> df1 = DataFrame(merge(common_data, Dict("C" => [100, 200, 300])))
> df2 = DataFrame(merge(common_data, Dict("C" => [400, 500, 600])))
> df3 = DataFrame(merge(common_data, Dict("C" => [700, 800, 900])))
> 
> ```

If I understood correctly what you want, something like that might help:

```julia
tmp = innerjoin(df1,df2, on = [:A,:B], makeunique = true)
res = innerjoin(tmp, df3, on = [:A,:B], makeunique = true)

```

---

<div class="post-metadata">

**Author:** ![nilshg](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nilshg/32/2283_2.png) [@nilshg](https://discourse.julialang.org/u/nilshg)\
**Post date:** [August 18, 2023, 12:35pm UTC](https://discourse.julialang.org/t/vcat-dataframe-columns-based-on-multiple-columns-in-julia/102932/3 "2023-08-18T12:35:34Z")

</div>

I’m on the phone so take with a grain of salt but you can do something like

```julia
reduce((x, y) -> innerjoin(x, y, on = [:A, :B]), (df1, df2, df3))

```

---

<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:** [August 18, 2023, 2:55pm UTC](https://discourse.julialang.org/t/vcat-dataframe-columns-based-on-multiple-columns-in-julia/102932/4 "2023-08-18T14:55:53Z")

</div>

```julia
julia> innerjoin(df1,df2,df3, on=[:A,:B], makeunique=true)
3×5 DataFrame
 Row │ A B C C_1 C_2   
     │ Int64 Int64 Int64 Int64 Int64
─────┼───────────────────────────────────
   1 │ 1 10 100 400 700
   2 │ 2 20 200 500 800
   3 │ 3 30 300 600 900

```

---

<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:** [August 18, 2023, 4:37pm UTC](https://discourse.julialang.org/t/vcat-dataframe-columns-based-on-multiple-columns-in-julia/102932/5 "2023-08-18T16:37:09Z")

</div>

```julia
renamecols : a Pair specifying how columns of left and right data frames should be renamed in the
       resulting data frame. Each element of the pair can be a string or a Symbol can be passed in which case       
       it is appended to the original column name; alternatively a function can be passed in which case it is       
       applied to each column name, which is passed to it as a String. Note that renamecols does not affect
       on columns, whose names are always taken from the left data frame and left unchanged.

```

The `renamecols` keyword allows some editing of the output column names, but, it seems, only in the case of two dataframes.  
I can’t find any indication for a use in the case of more than 2 dataframes.  
In the case in question it would be useful to be able to apply a function that uses, for example, the name of the dataframes to be intertwined to distinguish the 3 columns “C”

---

<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:** [August 20, 2023, 8:19am UTC](https://discourse.julialang.org/t/vcat-dataframe-columns-based-on-multiple-columns-in-julia/102932/6 "2023-08-20T08:19:49Z")

</div>

This is the same question as on [SO](https://stackoverflow.com/questions/76904909/vcat-dataframe-columns-based-on-multiple-columns-in-julia), where I answered what can be done.

> I can’t find any indication for a use in the case of more than 2 dataframes.

We decided not to add it, as there was no easy way to specify the `renamecols` argument for more than two tables. Now, thinking of it, maybe we could allow passing a tuple of values? If this is something that would be useful, can you please open an issue.

Note that for the same reason when joining more than two data frames one cannot separately specify the `on` keyword argument columns for multiple tables (which is allowed for two tables case). Again - we could discuss if this is really needed.

My initial thinking was that when joining more than 2 tables one really should pre-process the tables.

Also, in general, if there are only 3 tables one can run two inner-joins operations in sequence with `renamecols` passed (by extension of what @Rudi79 proposed above).

---

<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:** [August 20, 2023, 8:48am UTC](https://discourse.julialang.org/t/vcat-dataframe-columns-based-on-multiple-columns-in-julia/102932/7 "2023-08-20T08:48:19Z")

</div>

Totally agree.  
I don’t think it’s a function so much in demand as to justify the complications of development and also in use.
