R Adding Days to a Date

R adding days to a date

Use +

> as.Date("2001-01-01") + 45
[1] "2001-02-15"

How to subtract/add days from/to a date?

Just subtract a number:

> as.Date("2009-10-01")
[1] "2009-10-01"
> as.Date("2009-10-01")-5
[1] "2009-09-26"

Since the Date class only has days, you can just do basic arithmetic on it.

If you want to use POSIXlt for some reason, then you can use it's slots:

> a <- as.POSIXlt("2009-10-04")
> names(unclass(as.POSIXlt("2009-10-04")))
[1] "sec" "min" "hour" "mday" "mon" "year" "wday" "yday" "isdst"
> a$mday <- a$mday - 6
> a
[1] "2009-09-28 EDT"

How add 30 days to a date in r?

You need to convert your character column into Date column with the correct
format.

    as.Date("07/03/2015", format="%d/%m/%Y") + 30
[1] "2015-04-06"

How to add days of the week to the existing date's column in Rstudio

How's this work? First, we convert the date into the magic R format, and then extract it back in the format we want.

posix <- strptime(x = "2019-01-01 00:00:00", 
format = "%Y-%m-%d %H:%M:%S")
strftime(posix, format = "%Y-%m-%d %H:%M:%S %A")

Here, we're essentially exporting it in the exact same format, plus the %A operator that corresponds to the weekday.

Add a day to a date AND time string

Check the output for

as.POSIXct(datetime)
#[1] "2015-07-20"

it truncates the time component. You need to specify proper format to it since it is not in standard format.

as.POSIXct(datetime, format = "%Y-%m-%dT%H:%M:%OS")
#[1] "2015-07-20 16:33:59

Once you do that you can do

as.POSIXct(datetime, format = "%Y-%m-%dT%H:%M:%OS") + 24*60*60
#[1] "2015-07-21 16:33:59"

How to add days to a POSIXct object in R

Your time format is not being tested by as.POSIXct. This is why you get this result.

You can use the following format to get it correct:

library(lubridate)

# note the format option to get it correct
input_time = as.POSIXct("2018-05-05T14:14:05", format = "%Y-%m-%dT%H:%M:%OS")
input_time + lubridate::days(1)

[1] "2018-05-06 14:14:05 UTC"

or just use everything with functions from lubridate:

input_time <- lubridate::ymd_hms("2018-05-05T14:14:05")
input_time + lubridate::days(1)

[1] "2018-05-06 14:14:05 UTC"

Adding a Date column that corresponds to the value in the day of the week column in R

Try first just adding a column that has the consecutive dates

seq(as.Date("2016/1/3"), as.Date("2016/1/17"), "days")

R - Find x days from start date while keeping dates inbetween

This approach provides the row from each category with the minimum date, plus the five dates prior for each category (with value set to NA for these rows)

library(data.table)
setDT(data)[data[, .(date=seq(min(date)-5,by="day", length.out=6)), category], on=.(category,date)]

Output:

          date value category
1: 2020-06-03 NA 1
2: 2020-06-04 NA 1
3: 2020-06-05 NA 1
4: 2020-06-06 NA 1
5: 2020-06-07 NA 1
6: 2020-06-08 2 1
7: 2021-07-08 NA 2
8: 2021-07-09 NA 2
9: 2021-07-10 NA 2
10: 2021-07-11 NA 2
11: 2021-07-12 NA 2
12: 2021-07-13 1 2
13: 2021-08-11 NA 3
14: 2021-08-12 NA 3
15: 2021-08-13 NA 3
16: 2021-08-14 NA 3
17: 2021-08-15 NA 3
18: 2021-08-16 4 3
19: 2021-09-14 NA 4
20: 2021-09-15 NA 4
21: 2021-09-16 NA 4
22: 2021-09-17 NA 4
23: 2021-09-18 NA 4
24: 2021-09-19 5 4
date value category

Note: The above uses a join; an identical result can be achieved without a join by row-binding the first row for each category with the data.table generated similarly as above:

rbind(
setDT(data)[order(date), .SD[1],category],
data[,.(date=seq(min(date)-5,by="day",length.out=5),value=NA),category]
)

You indicate you have many columns, so if you are going to take this second approach, rather than explicitly setting value=NA in the second input to rbind, you can also just leave it out, and add fill=TRUE within the rbind()

A dplyr version of the same is:

bind_rows(
data %>%
group_by(category) %>%
slice_min(date) %>%
ungroup() %>%
mutate(date=as.Date(date)),
data %>%
group_by(category) %>%
summarize(date=seq(min(as.Date(date))-5,by="day", length.out=5), .groups="drop")
)

Output:

# A tibble: 24 x 3
date value category
<date> <dbl> <dbl>
1 2020-06-08 2 1
2 2021-07-13 1 2
3 2021-08-16 4 3
4 2021-09-19 5 4
5 2020-06-03 NA 1
6 2020-06-04 NA 1
7 2020-06-05 NA 1
8 2020-06-06 NA 1
9 2020-06-07 NA 1
10 2021-07-08 NA 2
# ... with 14 more rows

Update (9/21/22) -

If you want the NA values to be filled, simply add this to the end of either data.table pipeline:

 ...[,value:=max(value, na.rm=T), category]

or add this to the dplyr pipeline

... %>%
group_by(category) %>%
mutate(value=max(value, na.rm=T))


Related Topics



Leave a reply



Submit