1

We have an arbitrary dataset, called df:

enter <- c("2017-01-01", "2018-02-02", "2018-03-03") 
guest <- c("Foxtrot","Uniform","Charlie","Kilo")
disposal <- c("2017-01-05", "2018-02-05", "2018-03-09") 
rating <- c("60","50","50")
date <- c("2017-04-10", "2018-04-15", "2018-04-20")
clock <- c("16:02:00", "17:02:00", "18:02:00")
rolex <- c("20:10:00", "20:49:00", "17:44:00") 
df <- data.frame(enter,guest,disposal,rating,date,clock,rolex, stringsAsFactors = F)

What I try to accomplish is to change the columns enter, disposal, and date from character to date, using dplyr package. So, I came up with the following, simply by chaining it together:

library(dplyr)
library(chron)
df2 <- df %>% mutate(enter = as.Date(enter, format = "%Y-%m-%d")) 
%>% mutate(disposal = as.Date(disposal, format = "%Y-%m-%d")) 
%>% mutate(date = as.Date(date, format = "%Y-%m-%d"))

What I am after is this: which mutate function is needed from dplyr to get rid of the multiple chaining, i.e. when we have lots of columns with arbitrary namings that imply dates? I want to specify the columns by name, and then apply the as.Date function to change them from character to date.

Some solutions to different operations that are not applicable to this case:

1: convert column in data.frame to date

2: convert multiple columns to dates with lubridate and dplyr

3: change multiple character columns to date

For example, I've tried, but with no luck:

df2 <- df %>% mutate_at(data = df, each_of(c(enter, disposal, date)) = as.Date(format = "%Y-%m-%d"))

as given here: dplyr change many data types

As a bonus

Notice the clock and rolex columns. Using the chron package simply converts them to the right format, i.e. time instead of character

df2 <- df %>% mutate(clock = chron(times = clock)) %>% mutate(rolex = chron(times = rolex))

As suggested here: convert character to time in r

Now, is the same solution available without all the chaining, especially when we have an arbitrary amount of columns with different namings etc.?

Community
  • 1
  • 1
Wokkel
  • 319
  • 4
  • 12
  • 1
    `mutate_at` is totally correct, just that you use it in a very strange way. `df %>% mutate_at(vars(enter, disposal, date), funs(as.Date))` seems correct (plus format). – RolandASc Feb 21 '18 at 14:41
  • Your answer works fine as well. It is even more compact than the answer from qdread. Either way, thank you for another solution. – Wokkel Feb 22 '18 at 08:48
  • Both solutions are the same. I just explicitly provided the `format` argument, which happens to be the default in this case. If the dates were provided in a different format, you would have to specify that. – qdread Feb 22 '18 at 12:22

1 Answers1

4

You just need to tweak the arguments of mutate_at. Any additional arguments to as.Date are specified as arguments to mutate_at.

df2 <- df %>% mutate_at(vars(enter,disposal,date), as.Date, format="%Y-%m-%d")

The second part of your question has a similar solution.

df2 <- df2 %>% mutate_at(vars(clock, rolex), function(x) chron(times. = x))
qdread
  • 3,389
  • 19
  • 36