Convert numeric data such as "715" into Date "July-2015" in R - r

I would like to friendly ask a question about converting numeric data into Date format.
I would like to convert the numeric data like:
time1<-c(715, 1212, 0416)
to
July-2015, Dec-2012, Apr-2016
I have tried these code but it is not working.
time2<-as.Date(as.character(time1), format="%m%y")
Does anyone have some ideas to solve this issue?

Part of the issue is that "July 2015", "December 2012", and "April 2016" are not dates since the specific day is missing. Another approach is to convert to zoo::yearmon. Here, the numeric input needs to be converted to a string with leading zero so that the month is from 01 to 12:
library(zoo)
ym <- as.yearmon(sprintf("%04d",time1),format="%m%y")
ym
##[1] "Jul 2015" "Dec 2012" "Apr 2016"
The result is of class yearmon, which can then be coerced to Date:
class(ym)
##[1] "yearmon"
d <- as.Date(ym)
d
##[1] "2015-07-01" "2012-12-01" "2016-04-01"
class(d)
##[1] "Date"

Try lubridate::parse_date_time():
library(lubridate)
time2 <- parse_date_time(time1, orders = "my")
format.Date(time2, "%b-%Y")
[1] "juil.-2015" "déc.-2012" "avril-2016" # my locale lang is French

Related

Negative months as difference between two dates

I am aware that there are some posts similar to this here on stackoverflow. But they did not directly address my issue. Here is my issue:
I have a variable called earliest_cr_line which contains dates as Jan-01. This is a string variable. I need to create a variable called "test" which should contain the difference between earliest_cr_line and Dec-2007 in months. To this end, I ran the following codes:
library(zoo)
loan_data$earliest_cr_line_date <- as.yearmon(loan_data$earliest_cr_line, "%b-%y")
ref_date <- as.yearmon("Dec-07", "%b-%y")
loan_data$test <- round((as.Date(ref_date) -
as.Date(loan_data$earliest_cr_line_date))/(365.25/12))
However, the newly created variable test contains many negative numbers as well. I figured out that when converting earliest_cr_line from string to yearmon, R misinterpreted years which were before 1970. For example, yearmon converted Jan-60 into Nov 2060 instead of Nov 1960. That's what is causing the negative output. Any idea how I should approach this problem?
Thanks.
Date's integer is a day, making day-to-month determination inconsistent. yearmon's integer is a year, which makes a month just 1/12, a bit simpler to deal with. If you start with zoo's yearmon object, then I suggest you stick with it instead of trying convert to/from R's Date object.
Handling wrong years is an annoying Y2K problem ... while this below will generally work (assuming that everything you're looking at is in the past), I urge you to fix this problem at the source. (I am astounded that something somewhere still thinks that 2-digit years is acceptable. *shrug*)
vec <- c("Nov-60","Nov-70","Nov-71","Jan-01","Mar-05","Dec-07")
(out <- zoo::as.yearmon(vec, format="%b-%y"))
# [1] "Nov 2060" "Nov 1970" "Nov 1971" "Jan 2001" "Mar 2005" "Dec 2007"
(wrongcentury <- as.integer(gsub(".* ", "", out)) > as.integer(format(Sys.Date(), "%Y")))
# [1] TRUE FALSE FALSE FALSE FALSE FALSE
vec[wrongcentury]
# [1] "Nov-60"
zoo::as.yearmon(gsub("-", "-19", vec[wrongcentury]), format = "%b-%Y")
# [1] "Nov 1960"
out[wrongcentury] <- zoo::as.yearmon(gsub("-", "-19", vec[wrongcentury]), format = "%b-%Y")
out
# [1] "Nov 1960" "Nov 1970" "Nov 1971" "Jan 2001" "Mar 2005" "Dec 2007"
Edit: much more concise recommendation from G. Grothendieck:
out <- zoo::as.yearmon(vec, format="%b-%y")
out - 100 * (out > zoo::as.yearmon(Sys.Date()))
# [1] "Nov 1960" "Nov 1970" "Nov 1971" "Jan 2001" "Mar 2005" "Dec 2007"
If your source data ever comes close to 1920, then this inferential solution will further break. (More reason to fix it at the source :-)

convert "2014-05" into date format as "May 2015" for display in ggplot in R

I have date in this character format "2017-03" and I want to convert it in "March 2017" for display in ggplot in R. But when I try to convert it using as.Date("2017-03","%Y-%m") it gives NA
You can consider using zoo::as.yearmon function as:
library(zoo)
#Sample data
v <- c("2014-05", "2017-03")
as.yearmon(v, "%Y-%m")
#[1] "May 2014" "Mar 2017"
#if you want the month name to be in full. Then you can format yearmon type as
format(as.yearmon(v, "%Y-%m"), "%B %Y")
#[1] "May 2014" "March 2017"
Parse dates back and forth can be done like this:
The one you mentioned is done by quoting MKR:
Use zoo package
library(zoo)
date <- "2017-03"
as.yearmon(date, "%Y-%m")
#[1] "Mar 2017"
format(as.yearmon(date, "%Y-%m"), "%B %Y")
#[1] "March 2017"
If you want to parse March 2017 or other similar formats back to 2017-03:
Use hms package because base R doesn't provide a nice built-in class for date
library(hms)
DATE <- "March 1 2017"
parse_date(DATE, "%B %d %Y")
#[1] "2017-03-01"
Or if you are parsing dates with foreign language:
foreign_date <- "1 janvier 2018"
parse_date(foreign_date, "%d %B %Y", locale = locale("fr"))
#[1] "2018-01-01"
By using the locale = locale("language") you can parse dates with foreign months names to standard dates. Use this to check the language:
date_names_langs()
-Format:
-Year: %Y(4 digits) %y(2 digits; 00-69->2000-2069, 70-99 -> 1970-1999)
-Month: %m (2 digits), %b (abbreviation: Jan), %B full name January
-Day: %d (2 digits)

Convert "September 2017" to Date

Sorry about another date-question, but I couldn't find an answer.
I have a date-type "September 2017" and need to convert it to "30.09.2017" (last day of month — for all months of all years).
I've tried:
date <- as.Date(date), "%B %d %Y")
+ variations of %d%m%y
And that:
library(zoo)
date <- as.Date(as.yearmon(date))
But every time I have NA.
This works for me:
> library(zoo)
> s = "September 2017"
> as.yearmon(s)
[1] "Sep 2017"
If I then convert to date, it gets the first of the month:
> as.Date(as.yearmon(s))
[1] "2017-09-01"
This seems to be exactly what you are doing but you don't explicitly show us where your "September 2017" string is so I suspect a problem there...
As for the "30th", what are you going to do about February? You can use frac=1 to get the last day of the month (hat tip #Henrik):
> as.Date(as.yearmon(s),frac=1)
[1] "2017-09-30"
> as.Date(as.yearmon("February 2018"),frac=1)
[1] "2018-02-28"
> as.Date(as.yearmon("February 2020"),frac=1)
[1] "2020-02-29"

Converting factor YYYY/MM to year-month class

I have dataframe with a column of dates of the form YYYY/MM, factor class, and I wish to convert it to date class. E.g. 2000/01 -> Jan 2000
I note that as.Date() is unable to handle date formats without the day component. I have tried using the as.yearmon() function from the zoo package.
library('zoo')
as.yearmon(factor("2000-01")) # It works with YYYY-MM format
# [1] "Jan 2000"
as.yearmon(factor("2000/01"))
# [1] NA
as.yearmon(factor("2000/01"),"%y/%m")
# [1] NA
I'm looking for a function that will turn factor("2000/01") to "Jan 2000". Any help would be kindly appreciated.
If as.Date has a problem with the day of month not being present, then for your purposes you can temporarily feed it with any day:
# Generate 10 "YYYY/MM"
n <- 10
our_dates <- paste(sample(1000:2000, n), sample(11:12, n, replace = TRUE), sep = "/")
our_dates
[1] "1027/12" "1657/12" "1180/11" "1646/12" "1012/12" "1684/12" "1693/11" "1835/11"
[9] "1916/11" "1073/12"
# Dirty fix, add a "day of month" to our dates
our_dates <- paste0(our_dates, "/01")
our_dates
[1] "1027/12/01" "1657/12/01" "1180/11/01" "1646/12/01" "1012/12/01" "1684/12/01"
[7] "1693/11/01" "1835/11/01" "1916/11/01" "1073/12/01"
# Format as dates
x <- as.Date(our_dates,"%Y/%m/%d")
# Now print out in your fromat:
format(x, format = "%b %Y")
[1] "Dec 1027" "Dec 1657" "Nov 1180" "Dec 1646" "Dec 1012" "Dec 1684" "Nov 1693"
[8] "Nov 1835" "Nov 1916" "Dec 1073"

date objects in month day format

I was wondering if there is a way for R to turn this format into any date object. The format is 'month [space] day'. For example: Jan 1 or Jul 29 or Jul 30. I just want those examples to be read as a date object so I can manipulate them.
Yes, use as.Date, but you also have to specify a year:
x <- c("Jan 1", "Jul 29", "Jul 30")
as.Date(paste("2012", x), format="%Y %b %d")
[1] "2012-01-01" "2012-07-29" "2012-07-30"
See ?as.Date for more help on Date objects, and ?strptime for help on the formatting codes.

Resources