0

My data has date info with numeric format of decimal, and which makes October subset as Jan.(010=>1) Because of this, as.POSIXct and as.Date are not applicable. When using substring(or substr) to take last two digit, it automatically converted to character, then 010 becomes 1.

num<-c(2019.009, 2019.010,2019.011)

Y<-as.numeric(substring(num,1,4))
M<-as.numeric(substr(num, 7,8))
as.yearmon(paste(Y,M),"%Y %m")
  [1] "Sep 2019" "Jan 2019" "Nov 2019"

as.POSIXct(num, tx="GMT","%Y %m")
  Error in as.POSIXct.numeric(num, tx = "GMT", "%Y %m") : 
  'origin' must be supplied
as.Date(num, "%Y %m")
  Error in charToDate(x) : 
  character string is not in a standard unambiguous format
rocknRrr
  • 341
  • 1
  • 10

2 Answers2

3

in base R you could use functions like strptime/as.Date +strftime/format etc etc.

method 1:

strftime(strptime(sprintf("%.3f01",num),"%Y.0%m%d"),"%b %Y")

[1] "Sep 2019" "Oct 2019" "Nov 2019"

method 2:

format(as.Date(sprintf("%.3f01",num),"%Y.0%m%d"),"%b %Y")

[1] "Sep 2019" "Oct 2019" "Nov 2019"

Of course you could mix the functions up, eg strptime + format etc

if you are using the zoo library, you could do:

zoo::as.yearmon(sprintf("%.3f", num), "%Y.0%m")

[1] "Sep 2019" "Oct 2019" "Nov 2019"
Onyambu
  • 67,392
  • 3
  • 24
  • 53
2

You can use sprintf to have fixed number of decimal places and use sub to extract first 4 digits and last 2 digits in the data and convert to year month class.

num<-c(2019.009, 2019.010,2019.011)
zoo::as.yearmon(sub('(\\d{4})\\..(\\d{2})$', '\\1-\\2', sprintf('%0.3f', num)))
#[1] "Sep 2019" "Oct 2019" "Nov 2019"

Your original code will also work after using sprintf :

num <- sprintf('%0.3f', num)
Y<-as.numeric(substring(num,1,4))
M<-as.numeric(substr(num, 7,8))
zoo::as.yearmon(paste(Y,M),"%Y %m")
#[1] "Sep 2019" "Oct 2019" "Nov 2019"
Ronak Shah
  • 377,200
  • 20
  • 156
  • 213