dloudtrain
dloudtrain

Reputation: 301

Changing the number on a specific position in a datetime in R

I would like to know whether there is a way to change a number on a specific position in a datetime?

I have a dataframe [df] like this:

id    created_at            diff
1     2020-04-08 14:30:47   89  
2     2020-04-08 14:30:47   0
3     2020-04-08 15:30:47   78
4     2020-04-08 15:30:47   0

I would like to change the created_at value for the rows with diff = 0, where I would like to add 10 minutes, or at possibly change number on positon 15 by adding 1.

The desirable result would look like this:

id    created_at            diff
1     2020-04-08 14:30:47   89  
2     2020-04-08 14:40:47   0
3     2020-04-08 15:30:47   78
4     2020-04-08 15:40:47   0

Is there any way of doing this? Thank you very much for any suggestions!

Upvotes: 1

Views: 454

Answers (4)

Chris Ruehlemann
Chris Ruehlemann

Reputation: 21400

Perhaps not the simplest, but this regex solution works:

df$created_at[df$difference == 0] <- 
  paste(sub("(^[^:]+:).*", "\\1", df$created_at[df$difference == 0]), 
        as.numeric(sub(".*\\d{2}:(\\d{2}):\\d{2}", "\\1", df$created_at[df$difference == 0])) +10,
        sub(".*(:\\d{2}).*$", "\\1", df$created_at[df$difference == 0]), sep = "")

Explanation:

First you target the date values associated with difference == 0. To these values you apply the following operations, namely

  1. cut the dates into relevant pieces (everything before the minutes, the minutes themselves, everything after the minutes),
  2. perform the sought change (adding 10 min), and
  3. paste the strings back together.

The only complicating factor is that in order for you to add the value 10 to the minutes, what the regex returns must be converted to type numeric:

Result:

df
           created_at difference
1 2020-04-08 14:30:47         89
2 2020-04-08 14:43:55          0
3 2020-04-08 14:37:02          2
4 2020-04-08 14:51:15          0

Data:

df <- data.frame(
  created_at = c("2020-04-08 14:30:47", "2020-04-08 14:33:55", "2020-04-08 14:37:02", "2020-04-08 14:41:15"),
  difference = c(89, 0, 2, 0), stringsAsFactors = F
)

Upvotes: 0

Kevin_Nguyen
Kevin_Nguyen

Reputation: 112

You can use code like this:

library(dplyr)
library(lubridate)

df %>% mutate(created_at = if_else(diff == 0, created_at + minutes(1), created_at))

Upvotes: 1

Ric S
Ric S

Reputation: 9247

One possible solution using the lubridate package is to first transform the created_at variable in a standard format (POSIXct) and then add 10 minutes only to a subset of the original dataframe, when the condition diff == 0 is verified.

library(lubridate)

df$created_at <- ymd_hms(df$created_at)
df[df$diff == 0, "created_at"] <- df[df$diff == 0, "created_at"] + minutes(10)

Output

#   id          created_at diff
# 1  1 2020-04-08 14:30:47   89
# 2  2 2020-04-08 14:40:47    0
# 3  3 2020-04-08 15:30:47   78
# 4  4 2020-04-08 15:40:47    0

Upvotes: 1

Aziz
Aziz

Reputation: 20705

Assuming the created_by column is a string (type character), you can convert it to a date/time, add 10 minutes, then convert back to string:

# Which rows to modify
r = which(df$diff == 0)

# read the created_at column, and convert to date/time
v = as.POSIXlt( df[r, 'created_at'])

# Add 10 minutes (10*60 seconds)
v = v + 10*60

# write values back (as string)
df[r,'created_at'] = as.character(v)

You can combine them into two lines:

r = which(df$diff==0)
df[r, 'created_at'] = as.character(as.POSIXlt(df[r, 'created_at']) + 10*60)

Resulting in:

  id          created_at diff
   1 2020-04-08 14:30:47   89
   2 2020-04-08 14:40:47    0
   3 2020-04-08 15:30:47   78
   4 2020-04-08 15:40:47    0

Upvotes: 1

Related Questions