43

I am using the lubridate package and applying the month function to extract month from date. I ran the str command on date field and I got

Factor w/ 9498 levels "01/01/1979","01/01/1980",..: 5305 1 1 1 1 1 1 1 1 1 ...

> v1$Date<-month(v1$Date)
Error in as.POSIXlt.character(as.character(x), ...) : 
character string is not in a standard unambiguous format

Here is an example of my data frame

https://drive.google.com/file/d/0B6cqWmwsEk20Q2dHblhXZi14Wk0/edit?usp=sharing

I don't know what I am doing wrong.

tonytonov
  • 22,820
  • 16
  • 72
  • 92
apTNow
  • 655
  • 1
  • 7
  • 19
  • 1
    possible duplicate of [R obtaining month and year from a date](http://stackoverflow.com/questions/9749598/r-obtaining-month-and-year-from-a-date) – RockScience Mar 24 '14 at 08:18
  • This question, the answers that follow, and any resulting code that others will have to support would be much clearer if the month and date differed in the examples, and if the handling of day and month were explicit. Dates like 01/01/1979 don't convey the necessary meaning when month and day are handled so differently in different contexts. – Argalatyr Mar 24 '14 at 08:19
  • After reading in your data, I'm unable to reproduce your error. – IRTFM Mar 24 '14 at 08:39
  • @IShouldBuyABoat, see my comment below. – Henrik Mar 24 '14 at 08:42
  • So the problem remains... if the OP posts data that doesn't reproduce the error, there is precious little the audience can do other than idle speculation. – IRTFM Mar 24 '14 at 08:45

5 Answers5

63

?month states:

Date-time must be a POSIXct, POSIXlt, Date, Period, chron, yearmon, yearqtr, zoo, zooreg, timeDate, xts, its, ti, jul, timeSeries, and fts objects.

Your object is a factor, not even a character vector (presumably because of stringsAsFactors = TRUE). You have to convert your vector to some datetime class, for instance to POSIXlt:

library(lubridate)
some_date <- c("01/02/1979", "03/04/1980")
month(as.POSIXlt(some_date, format="%d/%m/%Y"))
[1] 2 4

There's also a convenience function dmy, that can do the same (tip proposed by @Henrik):

month(dmy(some_date))
[1] 2 4

Going even further, @IShouldBuyABoat gives another hint that dd/mm/yyyy character formats are accepted without any explicit casting:

month(some_date)
[1] 2 4

For a list of formats, see ?strptime. You'll find that "standard unambiguous format" stands for

The default formats follow the rules of the ISO 8601 international standard which expresses a day as "2001-02-28" and a time as "14:01:02" using leading zeroes as here.

tonytonov
  • 22,820
  • 16
  • 72
  • 92
  • 2
    Given that the question was about `lubridate`, you may add `dmy(some_date)` as an alternative to `as.POSIXlt(some_date, format="%d/%m/%Y")` – Henrik Mar 24 '14 at 08:26
  • 4
    `lubridate::month` does not actually need the input to be any of those classes and it will properly read dd/mm/yyyy formats without even having a format string. – IRTFM Mar 24 '14 at 08:39
  • 1
    A side-note: it seems that `month` tries to coerce to `as.POSIXlt` and makes some guesses about the format. If dates are in 'dmy' and 'ymd' format, `month` guesses right. Take the first date in the text file from OP, "18/01/1979". This is clearly dmy. `month(as.factor("18/01/1979"))` works. ymd works: `month(as.factor("1979/01/18"))`. `month(as.factor("1979/18/01"))`does not work. So _given_ that the date format in the text file sample seems to be dmy, it might be other dates _not shown_ that are in a non-`month`-guessable format. – Henrik Mar 24 '14 at 08:41
51

Without the need of an external package:

if your date is in the following format:

myDate = as.POSIXct("2013-01-01")

Then to get the month number:

format(myDate,"%m")

And to get the month string:

format(myDate,"%B")
Scarabee
  • 4,907
  • 5
  • 25
  • 49
RockScience
  • 15,586
  • 22
  • 74
  • 117
14

you can convert it into date format by-

new_date<- as.Date(old_date, "%m/%d/%Y")} 

from new_date, you can get the month by strftime()

month<- strftime(new_date, "%m")

old_date<- "01/01/1979"
new_date<- as.Date(old_date, "%m/%d/%Y")
new_date
#[1] "1979-01-01"
month<- strftime(new_date,"%m")
month
#[1] "01"
year<- strftime(new_date, "%Y")
year
#[1] "1979"
user2100721
  • 3,377
  • 2
  • 17
  • 28
Jitesh Khurana
  • 147
  • 1
  • 5
1

Her is another R base approach:

From your example: Some date:

Some_date<-"01/01/1979"

We tell R, "That is a Date"

Some_date<-as.Date(Some_date)

We extract the month:

months(Some_date)

output: [1] "January"

Finally, we can convert it to a numerical variable:

as.numeric(as.factor(months(Some_date)))

outpt: [1] 1
Cro-Magnon
  • 1,707
  • 17
  • 24
0

For some time now, you can also only rely on the data.table package and its IDate class plus associated functions. (Check ?as.IDate()). So, no need to additionally install lubridate.

require(data.table)

some_date <- c("01/02/1979", "03/04/1980")
month(as.IDate(some_date, '%d/%m/%Y')) # all data.table functions
andschar
  • 1,703
  • 1
  • 14
  • 26