replace only date in PosixCt class
Asked Answered
B

2

5

I have a large dataframe of dates in PosixCt format. My objective is simple: to change all of the dates to one day - 2016-05-01 - while keeping all of the times the same. How would I proceed to replace the first 10 characters in a string (of every row) if I convert sample$newtime to character?

> class(sample$newtime)
[1] "POSIXct" "POSIXt" 

> head(sample)
                      newtime

1 2016-05-01 02:25:34
2 2016-05-01 02:20:23
3 2016-05-01 02:13:58
4 2016-05-01 02:10:33
5 2016-05-01 02:07:36
6 2016-05-01 02:03:01
> dim(sample)

    [1] 92020     1
> range(sample$newtime)
[1] "2015-01-01 01:04:29 MSK" "2016-06-15 12:45:03 MSK"
Butch answered 11/7, 2016 at 13:11 Comment(0)
C
9

You can use the date function from lubridate package, for example:

library(lubridate)
x = Sys.time()
y = Sys.time()

x
# [1] "2016-07-11 09:16:40 EDT"
y
# [1] "2016-07-11 09:16:45 EDT"

vec <- c(x, y)
date(vec)
# [1] "2016-07-11" "2016-07-11"
date(vec) <- "2015-01-01"           # change the date here
vec
# [1] "2015-01-01 09:16:40 EST" "2015-01-01 09:16:45 EST"
Canonicals answered 11/7, 2016 at 13:19 Comment(1)
can that be used within pipe notation? mutate for instance?Divulgate
U
4

Here are some alternatives. Each changes the date part to 2016-06-01. No packages are used.

1) sub Replace the leading non-spaces with the date and convert back to POSIXct. Note that sub automatically converts p to character so we do not need to do that explicitly. No packages are used:

as.POSIXct(sub("\\S+", "2016-06-01", p))

1a) This is a similar alternative. The replacement converts it back to POSIXct:

replace(p, TRUE, sub("\\S+", "2016-06-01", p))

2) arithmetic Another possibility is to subtract off the date and add on the new one. There may be time zone problems if we do not use format as shown:

p - as.POSIXct(as.Date(format(p))) + as.POSIXct("2016-06-01")

3) POSIXlt list This converts to POSIXlt lists, resets the year, mon and mday components and in the last line converts back.

toList <- function(x) unclass(as.POSIXlt(x))
m <- modifyList(toList(p), toList("2016-06-01")[c("year", "mon", "mday")])
as.POSIXct(structure(m, class = "POSIXlt"))

4) POSIXlt This converts to POSIXlt and sets the components directly:

with(unclass(as.POSIXlt("2016-06-01")), {
    p.lt <- as.POSIXlt(p)
    p.lt$year <- year
    p.lt$mon <- mon
    p.lt$mday <- mday
    as.POSIXct(p.lt)
})

Note: The input p used in all the solutions above in reproducible form is:

p <- structure(c(1462083934, 1462083623, 1462083238, 1462083033, 1462082856, 
    1462082581), class = c("POSIXct", "POSIXt"), tzone = "")
Underlinen answered 11/7, 2016 at 13:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.