This question hit the R-help list, and I thought I'd list all the given solutions, including mine using regular expressions:
This person had a variable 'x':
x [1] "2005-09-01"
And he wanted to create three variables, y, m, and d, such that:
y = 2005
m = 09
d = 01
My regular expression solution:
x <- "2005-09-01" pattern <- '([[:digit:]]{4})-([[:digit:]]{2})-([[:digit:]]{2})' y <- sub(pattern, '\\1', x) m <- sub(pattern, '\\2', x) d <- sub(pattern, '\\3', x)
Sub uses POSIX-extended regular expressions. It searches for the first argument, the pattern, and replaces it with the second argument in the variable defined by the third argument. [[:digit:]] is a match-any-digit operator; it matches the characters 0-9. The {#} is the interval operator, where what's inside the bracket's is a count. So [[:digit:]]{4} means match 4 digits. All together, ([[:digit:]]{4})-([[:digit:]]{2})-([[:digit:]]{2}) means "Match 4 digits followed by a dash followed by 2 digits followed by a dash followed by 2 digits.
By surrounding pieces of the search pattern in parentheses, we create back-references, which can be used in the replacement (second argument) like variables, \\1 to \\9, in the order that they appear in the pattern. When we replace the pattern with '\\1', that means return what is in the first set of parentheses, or the first four digits before a dash before two digits before a dash before another two digits.
Note: most of the time, we'd use single slashes to escape a character (i.e. \1), but R needs double slashes (i.e. \\1).
If you're interested in regular expressions, this site is quite helpful: http://www.cs.utah.edu/dept/old/texinfo/regex/regex_toc.html.
Gabor followed this up with:
library(gsubfn) x <- "2005-09-01" re <- "([[:digit:]]{4})-([[:digit:]]{2})-([[:digit:]]{2})" strapply(x, re, ~ c(year = year, month = month, day = day), backref = -3)[[1]]
"gsubfn" requires another package to be installed as well, "proto". This uses my pattern and splits it up into the specified vector. Could be handy, I imagine.
Frede's solution:
as.Date("2005-09-01","%Y-%m-%d") [1] "2005-09-01" format(as.Date("2005-09-01","%Y-%m-%d"),"%Y") [1] "2005" format(as.Date("2005-09-01","%Y-%m-%d"),"%d") [1] "01" format(as.Date("2005-09-01","%Y-%m-%d"),"%m") [1] "09"
Arun's solution:
x <- as.POSIXct("2005-09-01") x [1] "2005-09-01 GMT" x.lt <- as.POSIXlt(x) x$mon+1 x.lt$mon+1 [1] 9 x.lt$year+1900 [1] 2005 dput(x.lt) structure(list(sec = 0, min = 0L, hour = 0L, mday = 1L, mon = 8L, year = 105L, wday = 4L, yday = 243L, isdst = 0L), .Names = c("sec", "min", "hour", "mday", "mon", "year", "wday", "yday", "isdst" ), class = c("POSIXt", "POSIXlt"), tzone = "GMT") x.lt$mday [1] 1
Brian's solution:
zz <- strptime("2005-09-01","%Y-%m-%d") zz$year + 1900 [1] 2005 zz$mon + 1 [1] 9 zz$mday [1] 1
Gabor's solution:
library(chron) attach(month.day.year(chron(unclass(as.Date("2005-09-01"))))) year [1] 2005 month [1] 9 day [1] 1
or
library(chron) with(month.day.year(chron(unclass(as.Date("2006-09-01")))), { # computations involving variables month, day and year }