简体   繁体   中英

Convert Factor to Date (Year-Month)

My data column looks like...

date
<fctr>
14-Jan
14-Feb
14-Mar
15-Jan

Just wondering how to turn this into a date, because when I punch this code in I get NA's

hand$date <- as.Date(hand$date, format = "%y-%b")

date
<fctr>
NA
NA
NA
NA

Thanks for the help!

The OP has requested to convert Year-Mon (without day of the month) to Date from a data.frame column which is a factor. Without day of the month, the date is incomplete which produces NA s.

There are various options available to deal with incomplete dates.

as.Date() with day of the month supplemented

As suggested in a similar form by db :

as.Date(paste0(hand$date, "-01"), "%y-%b-%d")
#[1] "2014-01-01" "2014-02-01" "2014-03-01" "2015-01-01"

lubridate::ymd()

The ymd() function of the lubridate package has a truncated parameter to parse incomplete dates:

lubridate::ymd(hand$date, truncated = 1L)
#[1] "2014-01-01" "2014-02-01" "2014-03-01" "2015-01-01"

Note that lubridate automatically has assumed the first day of each month.

zoo::as.yearmon() and zoo::as.Date()

The option to use the as.yearmon() function from the zoo package has already been suggested by Sagar and statoptim .

The answer of Sagan is incomplete because as.yearmon() returns an object of class yearmon but not Date :

str(zoo::as.yearmon(hand$date, "%y-%b"))
#Class 'yearmon'  num [1:4] 2014 2014 2014 2015

The answer of statoptim is unnecessarily complicated as yearmon can directly be coerced to Date :

zoo::as.Date(zoo::as.yearmon(hand$date, "%y-%b"))
#[1] "2014-01-01" "2014-02-01" "2014-03-01" "2015-01-01"

Note that we have to use zoo::as.Date() if we haven't loaded zoo beforehand because base R's as.Date() doesn't know how to handle yearmon objects.

zoo::as.Date() has automatically assumed the first day of each month by default. The frac parameter can be used to control which day of the month is returned, eg,

zoo::as.Date(zoo::as.yearmon(hand$date, "%y-%b"), frac = 1)
#[1] "2014-01-31" "2014-02-28" "2014-03-31" "2015-01-31"

returns the last day of each month.

Caveat

It might be the case that the current locale may influence the interpretation of the abbreviated month names (which might be the case in statoptim's answer ).

There's an answer to a related question which suggests to check out the examples section of ?as.Date :

## read in date info in format 'ddmmmyyyy'
## This will give NA(s) in some locales; setting the C locale
## as in the commented lines will overcome this on most systems.
## lct <- Sys.getlocale("LC_TIME"); Sys.setlocale("LC_TIME", "C")
x <- c("1jan1960", "2jan1960", "31mar1960", "30jul1960")
z <- as.Date(x, "%d%b%Y")
## Sys.setlocale("LC_TIME", lct)
z

Following will work.

> library(zoo)
> as.yearmon("14-Jan", "%y-%b")
[1] "Jan 2014"

The zoo package documentation has the following example that also returns NA on my R

zoo::as.yearmon("mar07", "%b%y")

I am using gsub to replace "Jan" to "01". I see this is not the most efficient code but hope this helps you for now.

library(zoo)
df = data.frame(date = c("14-Jan", "14-Feb", "15-Jan"), stringsAsFactors = F)

month.abb
# [1] "Jan" "Feb" "Mar" "Apr" "May" "Jun" "Jul" "Aug" ....

month.num = substr( paste0("0", c(1:12)), start=c(rep(1,9), rep(2,3)), stop=3)
head(month.num)
# [1] "01" "02" "03" "04" "05" "06"

# can't think of or find ways to vectorize gsub 
for(i in 1:12) {
  df$date = gsub(df$date, pattern=month.abb[i], replacement=month.num[i])
}

as.Date(as.yearmon(df$date, format = "%y-%m"))
# [1] "2014-01-01" "2014-02-01" "2015-01-01"
  • update / comment since I don't have enough reputation to leave comments to Uwe Block 's answer. I found that "%b" (or passing month as abbreviation) does not work on my machine that have other language as operating system language. It works on another computer that has English as OS language. I do think question was posted because of the language issue. I was suggesting to convert to numeric values of month to bypass language issue not because of conversion to base date object.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM