# Most efficient way: create/mutate DataFrame time column

**URL:** <https://discourse.julialang.org/t/most-efficient-way-create-mutate-dataframe-time-column/31548>\
**Category:** General Usage\
**Created:** [November 26, 2019, 8:21pm UTC](https://discourse.julialang.org/t/most-efficient-way-create-mutate-dataframe-time-column/31548 "2019-11-26T20:21:06Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![Usor](https://avatars.discourse-cdn.com/v4/letter/u/8dc957/32.png) [@Usor](https://discourse.julialang.org/u/Usor)\
**Post date:** [November 26, 2019, 8:21pm UTC](https://discourse.julialang.org/t/most-efficient-way-create-mutate-dataframe-time-column/31548/1 "2019-11-26T20:21:06Z")

</div>

Suppose you have a `DataFrame`, which has a column called `Year` (with `Int64`). Then it has a column called `Month` (with `String`). Yes, suppose you have 12 rows with the integer year `2000` and the 12 months `January` to `December` as `String`s with that, and under it `2001` and its 12 months.

You look at it. Now you want to create a corresponding column with Julia’s own `Date` type.

What is the most direct, most efficient, and easy way to get the result whether using some querying package or only Julia’s own included tools?

* * *

I thought of using a `for` loop to create a new array, but it might not be the best here.

Alternatively, is it possible to simply enforce Julia’s recognition of `Date`s by editing a CSV beforehand somehow?

---

<div class="post-metadata">

**Author:** ![ExpandingMan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/expandingman/32/866_2.png) [@ExpandingMan](https://discourse.julialang.org/u/ExpandingMan)\
**Post date:** [November 26, 2019, 8:35pm UTC](https://discourse.julialang.org/t/most-efficient-way-create-mutate-dataframe-time-column/31548/2 "2019-11-26T20:35:19Z")

</div>

I don’t see a function in `Dates` for parsing month names, however there is a function for generating them.

You can do

```julia
mdict = Dict(monthname(i)=>i for i ∈ 1:12)
Date.(years, [mdict[m] for m ∈ months])

```

assuming the months and years are in two separate columns.

If you had a column with parseable timestamps you can set the column type with the `types` keyword, see the [CSV.jl documentation](https://juliadata.github.io/CSV.jl/stable/), but that doesn’t sound like it’s the case here.

---

<div class="post-metadata">

**Author:** ![Mattriks](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mattriks/32/351_2.png) [@Mattriks](https://discourse.julialang.org/u/Mattriks)\
**Post date:** [November 26, 2019, 11:40pm UTC](https://discourse.julialang.org/t/most-efficient-way-create-mutate-dataframe-time-column/31548/3 "2019-11-26T23:40:46Z")

</div>

Month names could be parsed like:

```julia
# df is the DataFrame described above
Date.(string.(df.Year).*"-".*df.Month, "y-U")

```

For info on the `"y-U"` string, see `?DateFormat`

---

<div class="post-metadata">

**Author:** ![Usor](https://avatars.discourse-cdn.com/v4/letter/u/8dc957/32.png) [@Usor](https://discourse.julialang.org/u/Usor)\
**Post date:** [November 27, 2019, 6:27pm UTC](https://discourse.julialang.org/t/most-efficient-way-create-mutate-dataframe-time-column/31548/4 "2019-11-27T18:27:07Z")

</div>

Thanks, both. I will have a look at that (and maybe come back to you).

---

<div class="post-metadata">

**Author:** ![Usor](https://avatars.discourse-cdn.com/v4/letter/u/8dc957/32.png) [@Usor](https://discourse.julialang.org/u/Usor)\
**Post date:** [November 27, 2019, 9:15pm UTC](https://discourse.julialang.org/t/most-efficient-way-create-mutate-dataframe-time-column/31548/5 "2019-11-27T21:15:44Z")

</div>

Your way, @Mattriks, gives me an error:

```julia
ArgumentError: Unable to parse date time. Expected directive DatePart(U) at char 6

```

* * *

I wonder, @ExpandingMan, if yours is really applicable to this situation. Maybe I don’t understand or I explained wrongly.

* * *

Let me try to explain (and someone can then extend this code):

```julia
### a simple DataFrame
df = DataFrame(
  Year = [2000, 2000, 2000, 2000],
  Month = ["January", "February", "March", "April"]
);

```

Question: how do you easily, automatically and most efficiently create a third column, which will have Julia’s `Date` type, where the elements/`Date`s will have the format according to`2000-01-01`, `2000-02-01`, which you would normally get from `Date(2000,1,1)`, `Date(2000,2,1)`, etc.?

---

<div class="post-metadata">

**Author:** ![Mattriks](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mattriks/32/351_2.png) [@Mattriks](https://discourse.julialang.org/u/Mattriks)\
**Post date:** [November 27, 2019, 9:23pm UTC](https://discourse.julialang.org/t/most-efficient-way-create-mutate-dataframe-time-column/31548/6 "2019-11-27T21:23:28Z")

</div>

Using the `df` in your last post, these both work for me:

```julia
df.date = Date.(.*(string.(df.Year), "-", df.Month), "y-U")
df.date2 = Date.(string.(df.Year).*"-".*df.Month, "y-U")

```

---

<div class="post-metadata">

**Author:** ![Usor](https://avatars.discourse-cdn.com/v4/letter/u/8dc957/32.png) [@Usor](https://discourse.julialang.org/u/Usor)\
**Post date:** [November 28, 2019, 2:26pm UTC](https://discourse.julialang.org/t/most-efficient-way-create-mutate-dataframe-time-column/31548/7 "2019-11-28T14:26:10Z")

</div>

That works.

I wish there were pre-made convenient functions for this kind of thing (which may be common encounters), even that it would nicely work with different `String` month names. I thought of it, but haven’t come up with a very nice solution.

Is there in any case an alternative to such code as you wrote closer to the source (earlier in the process)? For example, if you edit or make a CSV beforehand, can you do it in such a way (by doing a column in some way) so as to force `Date` recognition?

---

<div class="post-metadata">

**Author:** ![Mattriks](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mattriks/32/351_2.png) [@Mattriks](https://discourse.julialang.org/u/Mattriks)\
**Post date:** [November 28, 2019, 6:24pm UTC](https://discourse.julialang.org/t/most-efficient-way-create-mutate-dataframe-time-column/31548/8 "2019-11-28T18:24:44Z")

</div>

You can do (see `?CSV.File`):

```julia
CSV.read("myfile.csv", dateformat=dateformat"y-U", types=Dict(1=>Date))  

```

which assumes that column 1 contains e.g. 2000-January that can be converted to a Date. But that only works for single columns, I don’t know of a way for combining multiple columns into a `Date` in `CSV.read`.

---

<div class="post-metadata">

**Author:** ![Usor](https://avatars.discourse-cdn.com/v4/letter/u/8dc957/32.png) [@Usor](https://discourse.julialang.org/u/Usor)\
**Post date:** [November 28, 2019, 6:46pm UTC](https://discourse.julialang.org/t/most-efficient-way-create-mutate-dataframe-time-column/31548/9 "2019-11-28T18:46:02Z")

</div>

Thanks.
