# How to save the name of a DataFrame to a dictionary?

**URL:** <https://discourse.julialang.org/t/how-to-save-the-name-of-a-dataframe-to-a-dictionary/58409>\
**Category:** General Usage\
**Tags:** question\
**Created:** [April 2, 2021, 2:45am UTC](https://discourse.julialang.org/t/how-to-save-the-name-of-a-dataframe-to-a-dictionary/58409 "2021-04-02T02:45:55Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![HJW019](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/hjw019/32/22102_2.png) [@HJW019](https://discourse.julialang.org/u/HJW019)\
**Post date:** [April 2, 2021, 2:45am UTC](https://discourse.julialang.org/t/how-to-save-the-name-of-a-dataframe-to-a-dictionary/58409/1 "2021-04-02T02:45:55Z")

</div>

Hello!

I am writing a function by which I intend to read in a DataFrame, do some analysis with the data, and save the results and the name of the DataFrame in a dictionary. I am almost done except saving the DataFrame name. I tried various combinations of `:`, `Expr()`, `QuoteNode()`, but the best I could have achieved is saving the “entire” dataset in the dictionary. I only wish to save the name of the DataFrame.

Any suggestion will be appreciated! The following is a MWE.

```julia
using DataFrames

testdata = DataFrame(A = 1:2, B=["M", "F"]);

function test1(df::DataFrame)

    # doing some analysis here ...

    z = Dict{Symbol, Any}()  
    z[:dataname] = :($df) # wish to save name of the DataFrame
    return z
end    

dict1 = test1(testdata);
display(dict1[:dataname]) # returns the entire dataset, not what I want

```

---

<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:** [April 2, 2021, 5:26am UTC](https://discourse.julialang.org/t/how-to-save-the-name-of-a-dataframe-to-a-dictionary/58409/2 "2021-04-02T05:26:54Z")

</div>

Unfortunately, that is impossible in julia. Inside a function, you can’t see the name of the variable outside the function.

You will have to pass the string `"testdata"` to the function to give it a name.

---

<div class="post-metadata">

**Author:** ![tomerarnon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomerarnon/32/3170_2.png) [@tomerarnon](https://discourse.julialang.org/u/tomerarnon)\
**Post date:** [April 2, 2021, 5:30am UTC](https://discourse.julialang.org/t/how-to-save-the-name-of-a-dataframe-to-a-dictionary/58409/3 "2021-04-02T05:30:41Z")

</div>

^

Or associate the name with the dictionary like

```julia
testdata = DataFrame(A = 1:2, B=["M", "F"], name = "testdata");

```

---

<div class="post-metadata">

**Author:** ![sijo](https://avatars.discourse-cdn.com/v4/letter/s/da6949/32.png) [@sijo](https://discourse.julialang.org/u/sijo)\
**Post date:** [April 2, 2021, 6:53am UTC](https://discourse.julialang.org/t/how-to-save-the-name-of-a-dataframe-to-a-dictionary/58409/4 "2021-04-02T06:53:48Z")

</div>

An option to avoid repeating the variable name is to (ab)use keyword argument splatting:

```julia
using DataFrames
testdata = DataFrame(A = 1:2, B=["M", "F"]);

function test1(; kwargs...)
    df_name, df = first(kwargs)

    z = Dict{Symbol,Any}()
    z[:dataname] = df_name
    return z
end

julia> dict1 = test1(; testdata) # Semicolon required here!
Dict{Symbol, Any} with 1 entry:
  :dataname => :testdata

```

not sure it’s a good idea 🙂

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [April 2, 2021, 2:27pm UTC](https://discourse.julialang.org/t/how-to-save-the-name-of-a-dataframe-to-a-dictionary/58409/5 "2021-04-02T14:27:49Z")

</div>

> [@HJW019](#):
>
> do some analysis with the data, and save the results and the name of the DataFrame in a dictionary

I would suggest restructruring your code so that

1. you read in the dataframe and keep the name (eg in a `name => df` pair),
2. when doing analysis, work on the `df` part and carry the name, which you can automate easily with eg

```julia
lift(named_df, f, args....) = named_df[1] => f(named_df[2], args...)

```

3. just use the name when you are done.

---

<div class="post-metadata">

**Author:** ![HJW019](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/hjw019/32/22102_2.png) [@HJW019](https://discourse.julialang.org/u/HJW019)\
**Post date:** [April 2, 2021, 4:56pm UTC](https://discourse.julialang.org/t/how-to-save-the-name-of-a-dataframe-to-a-dictionary/58409/6 "2021-04-02T16:56:31Z")

</div>

I thank @pdeffebach , @tomerarnon , @sijo , and @Tamas_Papp for spending time responding to my question. Really appreciated. They are all informative to me. The suggestion of @sijo is quite good, though if possible I’d prefer not to have the semicolon there so as to keep the API clean.

@Tamas_Papp 's suggestion is … deep to me! I am still new to Julia, and after playing the lines for a while I still couldn’t fathom how to use them in my workflow. The following shows my silly, useless effort in trying to understand the code. Could @Tamas_Papp kind enough to elaborate? Many thanks.

```julia
using DataFrames
testdata = DataFrame(A = 1:2, B=["M", "F"]);

function f(data::DataFrame)
  res = sum(data[:, 1])
  return res
end    

mypair = ("my", testdata);
lift(named_df, f) = named_df[1] => f(named_df[2])
lift(mypair, f)

julia> lift(mypair, f)
"my" => 3

```

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [April 2, 2021, 5:25pm UTC](https://discourse.julialang.org/t/how-to-save-the-name-of-a-dataframe-to-a-dictionary/58409/7 "2021-04-02T17:25:51Z")

</div>

From the code you included I think you got the essence of my solution perfectly, so I am not sure what to elaborate on. Just write your transformation functions `f` and `lift` them.

---

<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:** [April 2, 2021, 5:27pm UTC](https://discourse.julialang.org/t/how-to-save-the-name-of-a-dataframe-to-a-dictionary/58409/8 "2021-04-02T17:27:47Z")

</div>

OP this might be a bit of an XY problem.

I think the real solution is to keep your data frames in Dicts so that each one has a name attached to it, and that named is actually stored someplace instead of just being the variable name you use in global scope.

---

<div class="post-metadata">

**Author:** ![DaymondLing](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/daymondling/32/8474_2.png) [@DaymondLing](https://discourse.julialang.org/u/DaymondLing)\
**Post date:** [April 2, 2021, 5:53pm UTC](https://discourse.julialang.org/t/how-to-save-the-name-of-a-dataframe-to-a-dictionary/58409/9 "2021-04-02T17:53:13Z")

</div>

If I understand @Tamas_Papp correctly, this may suit your needs

```julia
using DataFrames

mydata = ("testdata" => DataFrame(A = 1:2, B=["M", "F"]))
# use mydata.first and mydata.second to refer to the Pair elements

function test(in::Pair{String, DataFrame})
    df = in.second
    df.C = 3:4 # do stuff with df
    z = Dict{Symbol, Any}()  
    z[:dataname] = in.first # save name
    z[:dataframe] = df # save dataframe
    z[:pair] = in # save the pair if you like
    return z
end    

out = test(mydata)
out[:dataname]
out[:dataframe]
out[:pair]
mydata.second # changed as well

```

In dynamic languages, names are symbols that are bound to values or actual data objects: names are pointers to objects, objects don’t have names. In your example, the DataFrame is an object, Tamas suggested to use a Pair to collect a name (String) and the DataFrame object together.

---

<div class="post-metadata">

**Author:** ![sijo](https://avatars.discourse-cdn.com/v4/letter/s/da6949/32.png) [@sijo](https://discourse.julialang.org/u/sijo)\
**Post date:** [April 2, 2021, 6:50pm UTC](https://discourse.julialang.org/t/how-to-save-the-name-of-a-dataframe-to-a-dictionary/58409/10 "2021-04-02T18:50:36Z")

</div>

With destructuring you can also extract the name and the data from the pair, directly in the function signature:

```julia
using DataFrames

function test1((name, df))
    z = Dict{Symbol, Any}()
    z[:dataname] = name
    z[:result] = df[1,1] # or whatever
    return z
end

mydata = "testdata" => DataFrame(A = 1:2, B=["M", "F"])

julia> test1(mydata)
Dict{Symbol, Any} with 2 entries:
  :result => 1
  :dataname => "testdata"

```

Or of course you could write a macro `@test1` instead of a function (quite overkill I think).

---

<div class="post-metadata">

**Author:** ![HJW019](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/hjw019/32/22102_2.png) [@HJW019](https://discourse.julialang.org/u/HJW019)\
**Post date:** [April 3, 2021, 11:55am UTC](https://discourse.julialang.org/t/how-to-save-the-name-of-a-dataframe-to-a-dictionary/58409/11 "2021-04-03T11:55:19Z")

</div>

Thank you all again for the suggestions and advice; I learned a lot. The examples of @DaymondLing and @sijo are particularly illustrative! I think I can figure out my solution now.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [April 3, 2021, 1:02pm UTC](https://discourse.julialang.org/t/how-to-save-the-name-of-a-dataframe-to-a-dictionary/58409/12 "2021-04-03T13:02:05Z")

</div>

> [@DaymondLing](#):
>
> Tamas suggested to use a Pair to collect a name (String) and the DataFrame object together.

That, and also reusing existing transformations with `lift`. But that’s just a style issue, it can be coded either way.

---

<div class="post-metadata">

**Author:** ![DaymondLing](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/daymondling/32/8474_2.png) [@DaymondLing](https://discourse.julialang.org/u/DaymondLing)\
**Post date:** [April 3, 2021, 2:12pm UTC](https://discourse.julialang.org/t/how-to-save-the-name-of-a-dataframe-to-a-dictionary/58409/13 "2021-04-03T14:12:51Z")

</div>

Very neat, I forgot about destructuring right in the parameter list. Thank you.
