Change Format of Date Column - r

I need to turn one date format into another with RStudio, since for lubridate and other date related functions a standard unambiguous format is needed for further work. I've included a few examples and informations below:
Example-Dataset:
Function,HiredDate,FiredDate
Waitress,16-06-01 12:40:02,16-06-13 11:43:12
Chef,16-04-17 15:00:59,16-04-18 15:00:59
Current Date Format (POSIXlt) of HiredDate and FiredDate:
"%y-%m-%d %H:%M:%S"
What I want the Date Format of HireDate and FiredDate to be:
"%Y-%m-%d %H:%M:%S" / 2016-06-01 12:40:02
or
"%Y/%m/%d %H:%M:%S" / 2016/06/01 12:40:02

In principle, you can convert date and time for example using the strftime function:
d <- "2016-06-01 12:40:02"
strftime(d, format="%Y/%m/%d %H:%M:%S")
[1] "2016/06/01 12:40:02"
In your case, the year is causing trouble:
d <- "16-06-01 12:40:02"
strftime(d, format="%Y/%m/%d %H:%M:%S")
[1] "0016/06/01 12:40:02"
As Dave2e suggested, the two digit year can be read by %y:
strftime(d, format="%y/%m/%d %H:%M:%S")
[1] "16/06/01 12:40:02"
Assuming that your data comes from the 20st and 21st century, you can paste a 19 or 20 in front of the HireDate and FireDate:
current <- 16
prefixHire <- ifelse(substr(data$HireDate, 1, 2)<=currentYear,20,19)
prefixFire <- ifelse(substr(data$FireDate, 1, 2)<=currentYear,20,19)
data$HireDate = paste(prefixHire, data$HireDate, sep="")
data$FireDate = paste(prefixFire, data$FireDate, sep="")
The code generates a prefix by assuming that any date from a year greater than the current ('16) is actually from the 20th century. The prefix is then pasted to HireDate and FireDate.

Related

convert date with time formats [R]

how can i convert a date from a format like yyyymmdd H:M to yyyy-mm-dd H:M, basicaly from 20200101 00:00 to 2020-01-01 00:00. i have tried multiple as.Date formats and cant obtain the result i want
example of what i have :
dates <- c("20200101 00:00", "20200101 01:00")
want <- as.Date(have, format="%Y%m%d %H:%M")
the output:
> want<- as.Date(dates, format="%Y%m%d %H:%M")
> want
[1] "2020-03-01" "2020-03-01"
There's two pieces here. One is converting to date time class, such as POSIXt. Then there is how this object is printed. Under the hood it's all represented the same, but you can control how it's displayed.
The format argument in any of the conversion functions (as.Date or as_datetime) is describing how to parse the string representation into the components of a data time object (e.g. where in the string to find the minutes). You need to then use something like format or strftime to then control how the values are printed/displayed.
Below is what I think you're aiming for:
dates_as_strings <- c("20200101 00:00", "20200101 01:00")
dates_as_datetime_objs <- lubridate::as_datetime(dates_as_strings, format="%Y%m%d %H:%M")
strftime(dates_as_datetime_objs, "%Y-%m-%d %H:%M", tz = "UTC")
#> [1] "2020-01-01 00:00" "2020-01-01 01:00"
Created on 2021-05-21 by the reprex package (v1.0.0)

Convert character YYYY-MM-00 into date YYYY-MM in R

I imported Excel data into R and I have a problem to convert dates.
In R, my data are character and look like :
date<-c('1971-02-00 00:00:00', '1979-06-00 00:00:00')
I would like to convert character into date (MM/YYYY) but the '00' value used for days poses a problem and 'NA' are returned systematically.
It works when I manually replace '00' with '01' and then use as.yearmon, ymd and format. But I have lots of dates to change and I don't know how to change all my '00' into '01' in R.
# data exemple
date1<-c('1971-02-00 00:00:00', '1979-06-00 00:00:00')
# removing time -> doesn't work because of the '00' day
date1c<-format(strptime(date1, format = "%Y-%m-%d"), "%Y/%m/%d")
date1c<-format(strptime(date1, format = '%Y-%m'), '%Y/%m')
# trying to convert character into date -> doesn't work either
date1c<-ymd(date1)
date1c<-strptime(date1, format = "%Y-%m-%d %H:%M:%S")
date1c<-as.Date(date1, format="%Y-%m-%d %H:%M:%S")
date1c<as.yearmon(date1, format='%Y%m')
# everything works if days are '01'
date2<-c('1971-02-01 00:00:00', '1979-06-01 00:00:00')
date2c<-as.yearmon(ymd(format(strptime(date2, format = "%Y-%m-%d"), "%Y/%m/%d")))
date2c
If you have an idea to do it or an another idea to solve my problem, I would be thankful!
Use gsub to replace -00 with -01.
date1<-c('1971-02-01 00:00:00', '1979-06-01 00:00:00')
date1 <- gsub("-00", "-01", date1)
date1c <-format(strptime(date1, format = "%Y-%m-%d"), "%Y/%m/%d")
> date1c
[1] "1971/02/01" "1979/06/01"
Another possibility could be:
as.Date(paste0(substr(date1, 1, 9), "1"), format = "%Y-%m-%d")
[1] "1971-02-01" "1979-06-01"
Here it extracts the first nine characters, pastes it together with 1 and then converts it into a date object.
These alternatives each accept a vector input and produce a vector as output.
Date output
These all will accept a vector as input and produce a Date vector as the output.
# 1. replace first occurrence of '00 ' with '01 ' and then convert to Date
as.Date(sub("00 ", "01 ", date1))
## [1] "1971-02-01" "1979-06-01"
# 2. convert to yearmon class and then to Date
library(zoo)
as.Date(as.yearmon(date1, "%Y-%m"))
## [1] "1971-02-01" "1979-06-01"
# 3. insert a 1 and then convert to Date
as.Date(paste(1, date1), "%d %Y-%m")
## [1] "1971-02-01" "1979-06-01"
yearmon output
Note that if you really are trying to represent just months and years then yearmon class directly represents such objects without the kludge of using an unused day of the month. Such objects are internally represented as a year plus a fraction of a year, i.e. year + 0 for January, year + 1/12 for February, etc. They display in a meaningful way, they sort in the expected manner and can be manipulated, e.g. take the difference between two such objects or add 1/12 to get the next month, etc. As with the others it takes a vector in and produces a vector out.
library(zoo)
as.yearmon(date1, "%Y-%m")
## [1] "Feb 1971" "Jun 1979"
character output
If you want character output rather than Date or yearmon output then these variations work and again accept a vector as input and produce a vector as output:
# 1. replace -00 and everything after that with a string having 0 characters
sub("-00.*", "", date1)
## [1] "1971-02" "1979-06"
# 2. convert to yearmon and then format that
library(zoo)
format(as.yearmon(date1, "%Y-%m"), "%Y-%m")
## [1] "1971-02" "1979-06"
# 3. convert to Date class and then format that
format(as.Date(paste(1, date1), "%d %Y-%m"), "%Y-%m")
## [1] "1971-02" "1979-06"
# 4. pick off the first 7 characters
substring(date1, 1, 7)
## [1] "1971-02" "1979-06"

parsing a character date time format in R

I am trying to parse a column into two variables, "date" and "time" in R. I have installed the lubridate library.
The current csv file has the following timestamp format: yyyyMMdd hh:mm a (e.g. '20170423 12:26 AM') and imports the column as character.
I'm trying this but its not working on my current variable 'Tran_Date' (below code doesn't work):
transactions_file <- as_date('Tran_Date', "%Y%m%d %H:%M %p")
I like the base R solution like this,
Tran_Date <- as.POSIXct("20170423 12:26 AM", format = "%Y%m%d %I:%M %p")
Tran_Date
#> [1] "2017-04-23 00:26:00 CEST"
transactions_file <- data.frame(
date = format(Tran_Date,"%m/%d/%Y"),
time = format(Tran_Date,"%H:%M")) # possibly add %p if you use %I
transactions_file
#> date time
#> 1 04/23/2017 00:26
with lubridate,
# install.packages(c("tidyverse"), dependencies = TRUE)
library(lubridate)
Tran_Date <- ymd_hm("20170423 12:26 AM")
then you could recycle the above or use some combination of day(Tran_Date) cbind paste with month(Tran_Date) and similar with paste(hour(Tran_Date), minute(Tran_Date), sep = ":") or most likely something smarter.

convert orderdate of format m/d/yy to YYYY-MM-DD in R

My orderdate is in factor and i want to convert it into from mm/dd/yy format to YYYY-MM-DD format.
orderdate : Factor w/ 155932 levels "1/1/2017 1:05:00 AM",..: 41 1 1 89 100 102 106 107 119 122 ...
I tried couple of things:
orders2017$newdate <- (factor(orders2017$orderdate))
orders2017$newdate1 <- as.Date(orders2017$newdate,format="%Y-%m-%d")
but nothing is working out and giving me new columns as empty. Any help is appreciated
If you really have values like "1/1/2017 1:05:00 AM" then those aren't dates, they are date times, and as such you have to specify formatting characters for both the date and time parts.
So, first you need to get your date times into a form R understands as such (e.g. POSIXct) by specifying all the parts of the date time:
test <- as.POSIXct("1/1/2017 1:05:00 AM", format = '%m/%d/%Y %I:%M:%S %p')
test
> test
[1] "2017-01-01 01:05:00 CST"
See ?strftime if you are not familiar with all the formatting placeholders used above, and note the conditions for use of %I and %p.
Then you can convert the POSIXct vector into the date format you desire
format(test, format = '%Y-%m-%d')
> format(test, format = '%Y-%m-%d')
[1] "2017-01-01"
A complication for you is that R has converted your character date times into a factor, so you need to convert them back to a character vector before converting to date times. For example (not tested as you didn't supply example data)
orders2017 <- transform(orders2017,
orderdate = as.POSIXct(as.character(orderdate),
format = '%m/%d/%Y %I:%M:%S %p'))
orders2017 <- transform(orders2017,
newdate = format(orderdate, format = '%Y-%m-%d'))
You were really close with as.Date(orders2017$newdate,format="%Y-%m-%d"), you just need to make the format string match your actual format.
Your actual format is mm/dd/YYYY, so use %m/%d/%Y as the format string:
as.Date("1/1/2017 1:05:00 AM", format = "%m/%d/%Y")
# [1] "2017-01-01"
Then the default printing of Date format objects is what you want.
So for your data,
orders2017$newdate1 <- as.Date(orders2017$newdate,format="%Y/%m/%d")
The time part will just be ignored.

Convert date format to CCYYMMDD HH:MM:SS

How one goes about to reformat date to CCYYMMDD HH:MM:SS TZ ? (the TZ is optional)
Here is related post but I would need the solution within R.
Here are my dates, which I would need to reformat.
library(lubridate)
startdate <- as.Date("2015-01-01")
week.dates <- seq(startdate, by="1 week", length.out=12)
dat.week <- week.dates[wday(week.dates) != 1 & wday(week.dates) != 7]
biz.week <- format(as.POSIXct(as.Date(dat.week)), tz="America/Los_Angeles",usetz=TRUE)
EDIT: Specifically, needed format is: 'YYYYMMDD{SPACE}hh:mm:ss[{SPACE}TMZ]'
Just try:
strftime(dat.week,format="%Y%m%d %H:%M %Z")
You can also use format or as.character instead of strftime.
I think you also requested the seconds, so here's a minor modification:
strftime(dat.week,format="%C%y%m%d %H:%M:%S %Z")

Resources