How to convert character to Date format in R?

2019-08-28 13:37发布

问题:

How to convert the below in character to Date format?

YYYY.MM

I am facing an issue dealing with zeroes after decimal points for month 10. Say

2012.10 

appears in my input source data as

2012.1

with the zero post decimal missing. How do I bring this back in the Date format?

回答1:

Since you have only year and month, you need to assign some value for day before you convert to date. In the example below, the day has arbitrarily been chosen as 15.

IF THE INPUT IS CHARACTER

dates = c("2012.10", "2012.01")

lubridate::ymd(paste0(year_month = dates, day = "15"))
#[1] "2012-10-15" "2012-01-15"

IF THE INPUT IS NUMERIC

dates = c(2012.10, 2012.01)

do.call(c, lapply(strsplit(as.character(dates), "\\."), function(d){
    if(nchar(d[2]) == 1){
        d[2] = paste0(d[2],"0")
    }
    lubridate::ymd(paste0(year = d[1], month = d[2], day = "15"))
}))
#[1] "2012-10-15" "2012-01-15"


回答2:

The code below uses the ymd() function from the lubridate package and sprintf() to coerce dates given in a numeric format

dates <- c(2012.1, 2012.01)

as well as dates given as a character string

dates <- c("2012.1", "2012.01")

where the part left of the decimal point specifies the year whereas the fractional part denote the month.

lubridate::ymd(sprintf("%.2f", as.numeric(dates)), truncated = 1L)
[1] "2012-10-01" "2012-01-01"

The format specification %.2f tells sprintf() to use 2 decimal places.

The parameter truncated = 1L indicates that one date element is missing (day) and should be completed by the default value (the first day of the month). Alternatively, the day of the month can be directly specified in the format specification to sprintf():

lubridate::ymd(sprintf("%.2f-15", as.numeric(dates)))
[1] "2012-10-15" "2012-01-15"


回答3:

The zoo package has a "yearmon" class for representing year and month without day. Internally it stores them as year + fraction where fraction = 0 for Jan, 1/12 for Feb, 2/12 for Mar and so on but it prints in a nicer format and sorts as expected. Assuming that your input, x, is numeric convert it to character with 2 digit month and then apply as.yearmon with the appropriate format.

library(zoo)

x <- c(2012.1, 2012.01)  # test data

as.yearmon(sprintf("%.2f", x), "%Y.%m")
## [1] "Oct 2012" "Jan 2012"

as.Date can be applied to convert a "yearmon" object to "Date" class if desired but normally that is not necessary.

as.Date(as.yearmon(sprintf("%.2f", x), "%Y.%m"))
## [1] "2012-10-01" "2012-01-01"