Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unable to format months with as.Date

Tags:

date

r

I'm missing something obvious with the "format" section of as.Date. Consider this example

d1 <- data.frame(d = c("1/Jan/1947", "1/Feb/1947", "1/Mar/1947"), d2 = c("Jan/1947", "Feb/1947", "Mar/1947"))

d1$date1 <- as.Date(x=d1$d, format="%d/%b/%Y")
d1$date2 <- as.Date(x=d1$d2, format="%b/%Y")

           d       d2      date1 date2
1 1/Jan/1947 Jan/1947 1947-01-01  <NA>
2 1/Feb/1947 Feb/1947 1947-02-01  <NA>
3 1/Mar/1947 Mar/1947 1947-03-01  <NA>

so my question is really simple -- I don't understand why the date1 works but date2 doesn't.

like image 337
tomw Avatar asked Sep 20 '11 05:09

tomw


2 Answers

The simplest answer is that a date is something which includes a day and if one is not specified, as.Date() gets confused. From the ?as.Date documentation:

If the date string does not specify the date completely, the returned answer may be system-specific. The most common behaviour is to assume that a missing year, month or day is the current one. If it specifies a date incorrectly, reliable implementations will give an error and the date is reported as ‘NA’. Unfortunately some common implementations (such as ‘glibc’) are unreliable and guess at the intended meaning.

When you think about it, a term such as "Mar/1947" is not, strictly speaking, a date - it's just a combination of month and year. A date is a specific day in March 1947 (or any other month + year) - since you don't specify one, you don't have a date.

like image 69
neilfws Avatar answered Oct 04 '22 15:10

neilfws


It is because d2 in your data.frame is a malformed date. It doesn't contain a day. To get round this, consider using the following:

d1$date2 <- as.Date(x=paste("1/",d1$d2, sep=""), format="%d/%b/%Y")
> d1
           d       d2      date1      date2
1 1/Jan/1947 Jan/1947 1947-01-01 1947-01-01
2 1/Feb/1947 Feb/1947 1947-02-01 1947-02-01
3 1/Mar/1947 Mar/1947 1947-03-01 1947-03-01
like image 44
Andrie Avatar answered Oct 04 '22 15:10

Andrie