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()
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()
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.
The lubridate package is amazing for this kind of thing:
> require(lubridate)
> month(date1)
[1] 3
> year(date1)
[1] 2012
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"))
You can use format
:
library(zoo)
x <- as.yearmon(Sys.time())
format(x,"%b")
[1] "Mar"
format(x,"%Y")
[1] "2012"
For large vectors:
y = as.POSIXlt(date1)$year + 1900 # x$year : years since 1900
m = as.POSIXlt(date1)$mon + 1 # x$mon : 0–11
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
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
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