Extract month and year from a zoo::yearmon object

RDateZoo

R Problem Overview


I have a yearmon object:

require(zoo)
date1 <- as.yearmon("Mar 2012", "%b %Y")
class(date1)
# [1] "yearmon"

How can I extract the month and year from this?

month1 <- fn(date1)
year1 <- fn(date1)

What function should I use in place of fn()

R Solutions


Solution 1 - R

Use the format() method for objects of class "yearmon". Here is your example date (properly created!)

date1 <- as.yearmon("Mar 2012", "%b %Y")

Then we can extract the date parts as required:

> format(date1, "%b") ## Month, char, abbreviated
[1] "Mar"
> format(date1, "%Y") ## Year with century
[1] "2012"
> format(date1, "%m") ## numeric month
[1] "03"

These are returned as characters. Where appropriate, wrap in as.numeric() if you want the year or numeric month as a numeric variable, e.g.

> as.numeric(format(date1, "%m"))
[1] 3
> as.numeric(format(date1, "%Y"))
[1] 2012

See ?yearmon and ?strftime for details - the latter explains the placeholder characters you can use.

Solution 2 - R

The lubridate package is amazing for this kind of thing:

> require(lubridate)
> month(date1)
[1] 3
> year(date1)
[1] 2012

Solution 3 - R

I know the OP is using zoo here, but I found this thread googling for a standard ts solution for the same problem. So I thought I'd add a zoo-free answer for ts as well.

# create an example Date 
date_1 <- as.Date("1990-01-01")
# extract year
as.numeric(format(date_1, "%Y"))
# extract month
as.numeric(format(date_1, "%m"))

Solution 4 - R

You can use format:

library(zoo)
x <- as.yearmon(Sys.time())
format(x,"%b")
[1] "Mar"
format(x,"%Y")
[1] "2012"

Solution 5 - R

For large vectors:

y = as.POSIXlt(date1)$year + 1900    # x$year : years since 1900
m = as.POSIXlt(date1)$mon + 1        # x$mon : 0–11

Solution 6 - R

Based on comments the result should be the month number (January = 1) and the 4 digit year so assuming that we have just run the code in the question we have the following. This uses no extra packages other than what is already used in the question, is very short and is much faster than any of the other solutions (see Benchmark section below).

cycle(date1)
## [1] 3
as.integer(date1)
## [1] 2012

Benchmark

On a yearmon object of length 1000 the solution above is about 1000x faster than any of the others for year and 200x faster for month.

library(zoo)
library(microbenchmark)
library(lubridate)

ym <- as.yearmon(rep(2000, 1000))

microbenchmark(
  as.integer(ym),
  as.numeric(format(ym, "%y")),
  as.POSIXlt(ym)$year + 1900,
  year(ym)
)

Unit: microseconds
                         expr     min       lq     mean   median       uq     max neval cld
               as.integer(ym)    18.2    27.90    28.93    29.15    31.15    51.2   100 a  
 as.numeric(format(ym, "%y")) 46515.8 47090.05 48122.28 47525.00 48080.25 69967.6   100   c
   as.POSIXlt(ym)$year + 1900 40874.4 41223.65 41798.60 41747.30 42171.25 44381.2   100  b 
                     year(ym) 40793.2 41167.70 42003.07 41742.40 42140.30 65203.3   100  b 
 
microbenchmark(
  cycle(ym),
  as.numeric(format(ym, "%m")),
  as.POSIXlt(ym)$mon + 1,
  month(ym)
)

Unit: microseconds
                         expr     min      lq      mean   median       uq     max neval cld
                    cycle(ym)   138.1   166.0   173.893   172.95   181.45   344.0   100 a  
 as.numeric(format(ym, "%m")) 46637.1 46954.8 47632.307 47325.90 47672.40 67690.1   100   c
       as.POSIXlt(ym)$mon + 1 40923.3 41339.1 41976.836 41689.95 42078.15 65786.4   100  b 
                    month(ym) 41056.4 41408.9 42082.975 41743.35 42164.95 66651.0   100  b 

Solution 7 - R

Having had a similar problem with data from 1800 to now, this worked for me:

data2$date=as.character(data2$date) 
lct <- Sys.getlocale("LC_TIME"); 
Sys.setlocale("LC_TIME","C")
data2$date<- as.Date(data2$date, format = "%Y %m %d") # and it works

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionadam.888View Question on Stackoverflow
Solution 1 - RGavin SimpsonView Answer on Stackoverflow
Solution 2 - RAri B. FriedmanView Answer on Stackoverflow
Solution 3 - RMatt BannertView Answer on Stackoverflow
Solution 4 - RJamesView Answer on Stackoverflow
Solution 5 - Ruser3226167View Answer on Stackoverflow
Solution 6 - RG. GrothendieckView Answer on Stackoverflow
Solution 7 - RanonymousView Answer on Stackoverflow