San
San

Reputation: 568

Adding something to a list of dates in a column

Supppose a data.table is:

dt <- structure(list(type = c("A", "B", "C"), dates = c("21-07-2011", 
    "22-11-2011,01-12-2011", "07-08-2012,14-08-2012,18-08-2012,11-10-2012"
    )), class = c("data.table", "data.frame"), row.names = c(NA, -3L))

Check it:

   type                                       dates
1:    A                                  21-07-2011
2:    B                       22-11-2011,01-12-2011
3:    C 07-08-2012,14-08-2012,18-08-2012,11-10-2012

I need to add, say, 5 to each of the dates in second column, ie, I want the result to be as under:

   type                                       dates
1:    A                                  26-07-2011
2:    B                       27-11-2011,06-12-2011
3:    C 12-08-2012,19-08-2012,23-08-2012,16-10-2012

Any help would be appreciated.

Upvotes: 1

Views: 88

Answers (2)

akrun
akrun

Reputation: 887028

Grouped by 'type', we split the 'dates' by the ,, (with strsplit), convert to a Date class object with dmy (from lubridate), add 5, format it to the original format of the data, paste it to single string and assign (:=) to update the 'dates' column in the dataset

library(lubridate)
library(data.table)
dt[, dates := paste(format(dmy(unlist(strsplit(dates, ","))) + 5, 
        '%d-%m-%Y'), collapse=','), by = type]
dt
#   type                                      dates
#1:    A                                  26-07-2011
#2:    B                       27-11-2011,06-12-2011
#3:    C 12-08-2012,19-08-2012,23-08-2012,16-10-2012

Another option without splitting, converting to Date, reformatting is regex method with gsubfn

library(gsubfn)
dt[, dates := gsubfn("^(\\d+)", ~ as.numeric(x) + 5, 
     gsubfn(",(\\d+)", ~sprintf(",%02d", as.numeric(x) + 5), dates))]
dt
#   type                                       dates
#1:    A                                  26-07-2011
#2:    B                       27-11-2011,06-12-2011
#3:    C 12-08-2012,19-08-2012,23-08-2012,16-10-2012

NOTE: Would assume the second method to be faster as we are not splitting, converting, pasteing etc.

Upvotes: 2

R. Schifini
R. Schifini

Reputation: 9313

Using only basic R you can do:

dt$dates = sapply(dt$dates, function(x){
  dates = as.Date(strsplit(x,",")[[1]], format = "%d-%m-%Y")
  paste(format(dates+5, '%d-%m-%Y'), collapse = ",")
})

Result:

> dt
   type                                       dates
1:    A                                  26-07-2011
2:    B                       27-11-2011,06-12-2011
3:    C 12-08-2012,19-08-2012,23-08-2012,16-10-2012

This procedure is practically the same as the one given by akrun, but without the extra libraries.

Upvotes: 3

Related Questions