# Transforming a DataFrame column by mapping with a Dict

**URL:** <https://discourse.julialang.org/t/transforming-a-dataframe-column-by-mapping-with-a-dict/61753>\
**Category:** Data\
**Tags:** dataframes\
**Created:** [May 25, 2021, 12:11am UTC](https://discourse.julialang.org/t/transforming-a-dataframe-column-by-mapping-with-a-dict/61753 "2021-05-25T00:11:36Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![anon71627001](https://avatars.discourse-cdn.com/v4/letter/a/a698b9/32.png) [@anon71627001](https://discourse.julialang.org/u/anon71627001)\
**Post date:** [May 25, 2021, 12:11am UTC](https://discourse.julialang.org/t/transforming-a-dataframe-column-by-mapping-with-a-dict/61753/1 "2021-05-25T00:11:36Z")

</div>

Let’s say I have a DataFrame and a Dict:

```julia
df = DataFrame(
    a = 1:3,
    b = ["beetle", "fly", "spider"])

arthropod_dict = Dict(
    "beetle" => "insect",
    "fly" => "insect",
    "spider" => "arachnid")

```

And I’d like to apply the Dict like a map to the DataFrame, producing

```julia
df = DataFrame(
    a = 1:3,
    b = ["beetle", "fly", "spider"],
    c = ["insect", "insect", "arachnid"])

```

Is there a way to do that using [`transform`](https://dataframes.juliadata.org/stable/lib/functions/#DataFrames.transform) or another DataFrame function so that I can apply the Dict within a [`@chain`](https://github.com/jkrumbiegel/Chain.jl) call?

---

<div class="post-metadata">

**Author:** ![anon71627001](https://avatars.discourse-cdn.com/v4/letter/a/a698b9/32.png) [@anon71627001](https://discourse.julialang.org/u/anon71627001)\
**Post date:** [May 25, 2021, 1:43am UTC](https://discourse.julialang.org/t/transforming-a-dataframe-column-by-mapping-with-a-dict/61753/2 "2021-05-25T01:43:34Z")

</div>

`transform(df, :b => ByRow(x -> arthropod_dict[x]) => :c)`

---

<div class="post-metadata">

**Author:** ![jd-foster](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jd-foster/32/35824_2.png) [@jd-foster](https://discourse.julialang.org/u/jd-foster)\
**Post date:** [May 25, 2021, 2:08am UTC](https://discourse.julialang.org/t/transforming-a-dataframe-column-by-mapping-with-a-dict/61753/3 "2021-05-25T02:08:49Z")

</div>

Nice (own) answer.  
I really like using the `@eachrow` macro in [DataFramesMeta.jl](https://juliadata.github.io/DataFramesMeta.jl/stable/) too:

```julia
@eachrow df begin
           @newcol c::Vector{String}
           :c = arthropod_dict[:b]
           end

```

also compatible within a `@chain` call:

```julia
@chain df begin
           filter(:a => >(2), _) # for example
           @eachrow begin
                @newcol c::Vector{String}
                :c = arthropod_dict[:b]
             end
end

```

It’s a bit more than a one-liner but handy for workflows with more complicated transforms.

---

<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:** [May 25, 2021, 6:16am UTC](https://discourse.julialang.org/t/transforming-a-dataframe-column-by-mapping-with-a-dict/61753/4 "2021-05-25T06:16:24Z")

</div>

Note that there is no requirement to use `transform` for everything in DataFrames, and at times I find it actively reducing code clarity. In my opinion (and this is nothing more!) this is one of those situations. I would write:

```julia
df[!, :c] = [arthropod_dict[x] for x ∈ df.b]

```

---

<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:** [May 25, 2021, 7:45am UTC](https://discourse.julialang.org/t/transforming-a-dataframe-column-by-mapping-with-a-dict/61753/5 "2021-05-25T07:45:55Z")

</div>

I would like to add a different solution (which, incidentally, also takes into account situations where the dictionary is not complete)

```julia
df = DataFrame(
    a = 1:4,
    b = ["beetle", "fly", "spider","unicorno"])

arthropod_dict = Dict(
    "beetle" => "insect",
    "fly" => "insect",
    "spider" => "arachnid")
dict=DataFrame(from=collect(keys(arthropod_dict)),to=collect(values(arthropod_dict)))
in this case a sort of function transpose(dataframe) would have been convenient

outerjoin(df,dict,on=:b=>:from)

```

a variant @nilshg solution

```julia
df[!, :c] = [get(arthropod_dict,x,"unknown") for x ∈ df.b]

```

---

<div class="post-metadata">

**Author:** ![sampope](https://avatars.discourse-cdn.com/v4/letter/s/e9c0ed/32.png) [@sampope](https://discourse.julialang.org/u/sampope)\
**Post date:** [June 23, 2021, 11:15pm UTC](https://discourse.julialang.org/t/transforming-a-dataframe-column-by-mapping-with-a-dict/61753/6 "2021-06-23T23:15:08Z")

</div>

Just a quick thank you for this. I’ve been wrestling for hours with trying to do just this and coming very close, but eating lots of errors.
